From fd27018caa5d0c9e8754640d8c3a2717d5879e2f Mon Sep 17 00:00:00 2001 From: Qstick Date: Mon, 8 Mar 2021 23:10:55 -0500 Subject: [PATCH] Automatic History cleanup setting --- frontend/src/Components/Page/PageConnector.js | 15 ++- frontend/src/History/History.js | 2 + frontend/src/History/HistoryOptions.js | 80 ++++++++++++++ .../src/History/HistoryOptionsConnector.js | 21 ++++ frontend/src/History/HistoryRow.css | 2 +- .../Configuration/ConfigService.cs | 102 +----------------- .../Configuration/IConfigService.cs | 20 +--- .../History/CleanupHistoryCommand.cs | 8 ++ src/NzbDrone.Core/History/History.cs | 2 +- .../History/HistoryRepository.cs | 6 ++ src/NzbDrone.Core/History/HistoryService.cs | 30 +++++- src/NzbDrone.Core/Jobs/TaskManager.cs | 36 +------ .../Config/HostConfigResource.cs | 4 +- .../Config/MediaManagementConfigController.cs | 27 ----- .../Config/MediaManagementConfigResource.cs | 54 ---------- 15 files changed, 171 insertions(+), 238 deletions(-) create mode 100644 frontend/src/History/HistoryOptions.js create mode 100644 frontend/src/History/HistoryOptionsConnector.js create mode 100644 src/NzbDrone.Core/History/CleanupHistoryCommand.cs delete mode 100644 src/Prowlarr.Api.V1/Config/MediaManagementConfigController.cs delete mode 100644 src/Prowlarr.Api.V1/Config/MediaManagementConfigResource.cs diff --git a/frontend/src/Components/Page/PageConnector.js b/frontend/src/Components/Page/PageConnector.js index 5f66ad81e..afd2743c5 100644 --- a/frontend/src/Components/Page/PageConnector.js +++ b/frontend/src/Components/Page/PageConnector.js @@ -7,7 +7,7 @@ import { saveDimensions, setIsSidebarVisible } from 'Store/Actions/appActions'; import { fetchCustomFilters } from 'Store/Actions/customFilterActions'; import { fetchIndexers } from 'Store/Actions/indexerActions'; import { fetchIndexerStatus } from 'Store/Actions/indexerStatusActions'; -import { fetchIndexerCategories, fetchIndexerFlags, fetchLanguages, fetchUISettings } from 'Store/Actions/settingsActions'; +import { fetchGeneralSettings, fetchIndexerCategories, fetchIndexerFlags, fetchLanguages, fetchUISettings } from 'Store/Actions/settingsActions'; import { fetchStatus } from 'Store/Actions/systemActions'; import { fetchTags } from 'Store/Actions/tagActions'; import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector'; @@ -47,6 +47,7 @@ const selectIsPopulated = createSelector( (state) => state.customFilters.isPopulated, (state) => state.tags.isPopulated, (state) => state.settings.ui.isPopulated, + (state) => state.settings.general.isPopulated, (state) => state.settings.languages.isPopulated, (state) => state.indexers.isPopulated, (state) => state.indexerStatus.isPopulated, @@ -57,6 +58,7 @@ const selectIsPopulated = createSelector( customFiltersIsPopulated, tagsIsPopulated, uiSettingsIsPopulated, + generalSettingsIsPopulated, languagesIsPopulated, indexersIsPopulated, indexerStatusIsPopulated, @@ -68,6 +70,7 @@ const selectIsPopulated = createSelector( customFiltersIsPopulated && tagsIsPopulated && uiSettingsIsPopulated && + generalSettingsIsPopulated && languagesIsPopulated && indexersIsPopulated && indexerStatusIsPopulated && @@ -82,6 +85,7 @@ const selectErrors = createSelector( (state) => state.customFilters.error, (state) => state.tags.error, (state) => state.settings.ui.error, + (state) => state.settings.general.error, (state) => state.settings.languages.error, (state) => state.indexers.error, (state) => state.indexerStatus.error, @@ -92,6 +96,7 @@ const selectErrors = createSelector( customFiltersError, tagsError, uiSettingsError, + generalSettingsError, languagesError, indexersError, indexerStatusError, @@ -103,6 +108,7 @@ const selectErrors = createSelector( customFiltersError || tagsError || uiSettingsError || + generalSettingsError || languagesError || indexersError || indexerStatusError || @@ -116,6 +122,7 @@ const selectErrors = createSelector( customFiltersError, tagsError, uiSettingsError, + generalSettingsError, languagesError, indexersError, indexerStatusError, @@ -177,6 +184,9 @@ function createMapDispatchToProps(dispatch, props) { dispatchFetchUISettings() { dispatch(fetchUISettings()); }, + dispatchFetchGeneralSettings() { + dispatch(fetchGeneralSettings()); + }, dispatchFetchStatus() { dispatch(fetchStatus()); }, @@ -212,6 +222,7 @@ class PageConnector extends Component { this.props.dispatchFetchIndexerCategories(); this.props.dispatchFetchIndexerFlags(); this.props.dispatchFetchUISettings(); + this.props.dispatchFetchGeneralSettings(); this.props.dispatchFetchStatus(); } } @@ -237,6 +248,7 @@ class PageConnector extends Component { dispatchFetchIndexerCategories, dispatchFetchIndexerFlags, dispatchFetchUISettings, + dispatchFetchGeneralSettings, dispatchFetchStatus, ...otherProps } = this.props; @@ -277,6 +289,7 @@ PageConnector.propTypes = { dispatchFetchIndexerCategories: PropTypes.func.isRequired, dispatchFetchIndexerFlags: PropTypes.func.isRequired, dispatchFetchUISettings: PropTypes.func.isRequired, + dispatchFetchGeneralSettings: PropTypes.func.isRequired, dispatchFetchStatus: PropTypes.func.isRequired, onSidebarVisibleChange: PropTypes.func.isRequired }; diff --git a/frontend/src/History/History.js b/frontend/src/History/History.js index fd31bdfb7..9cb71c1df 100644 --- a/frontend/src/History/History.js +++ b/frontend/src/History/History.js @@ -13,6 +13,7 @@ import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptions import TablePager from 'Components/Table/TablePager'; import { align, icons } from 'Helpers/Props'; import translate from 'Utilities/String/translate'; +import HistoryOptionsConnector from './HistoryOptionsConnector'; import HistoryRowConnector from './HistoryRowConnector'; class History extends Component { @@ -58,6 +59,7 @@ class History extends Component { { + const { + dispatchSaveGeneralSettings + } = this.props; + + const setting = { [name]: value }; + + this.setState(setting, () => { + dispatchSaveGeneralSettings(setting); + }); + } + + // + // Render + + render() { + const { + historyCleanupDays + } = this.state; + + return ( + + + History Cleanup + + + + + ); + } +} + +HistoryOptions.propTypes = { + historyCleanupDays: PropTypes.bool.isRequired, + dispatchSaveGeneralSettings: PropTypes.func.isRequired +}; + +export default HistoryOptions; diff --git a/frontend/src/History/HistoryOptionsConnector.js b/frontend/src/History/HistoryOptionsConnector.js new file mode 100644 index 000000000..860335818 --- /dev/null +++ b/frontend/src/History/HistoryOptionsConnector.js @@ -0,0 +1,21 @@ +import { connect } from 'react-redux'; +import { createSelector } from 'reselect'; +import { saveGeneralSettings } from 'Store/Actions/settingsActions'; +import HistoryOptions from './HistoryOptions'; + +function createMapStateToProps() { + return createSelector( + (state) => state.settings.general.item, + (generalSettings) => { + return { + ...generalSettings + }; + } + ); +} + +const mapDispatchToProps = { + dispatchSaveGeneralSettings: saveGeneralSettings +}; + +export default connect(createMapStateToProps, mapDispatchToProps)(HistoryOptions); diff --git a/frontend/src/History/HistoryRow.css b/frontend/src/History/HistoryRow.css index d63040c59..e43b1274e 100644 --- a/frontend/src/History/HistoryRow.css +++ b/frontend/src/History/HistoryRow.css @@ -7,7 +7,7 @@ .indexer { composes: cell from '~Components/Table/Cells/TableRowCell.css'; - width: 80px; + width: 150px; } .releaseGroup { diff --git a/src/NzbDrone.Core/Configuration/ConfigService.cs b/src/NzbDrone.Core/Configuration/ConfigService.cs index c51653df3..256f1b467 100644 --- a/src/NzbDrone.Core/Configuration/ConfigService.cs +++ b/src/NzbDrone.Core/Configuration/ConfigService.cs @@ -77,28 +77,16 @@ namespace NzbDrone.Core.Configuration return _repository.Get(key.ToLower()) != null; } - public bool AutoUnmonitorPreviouslyDownloadedMovies - { - get { return GetValueBoolean("AutoUnmonitorPreviouslyDownloadedMovies"); } - set { SetValue("AutoUnmonitorPreviouslyDownloadedMovies", value); } - } - public int Retention { get { return GetValueInt("Retention", 0); } set { SetValue("Retention", value); } } - public string RecycleBin + public int HistoryCleanupDays { - get { return GetValue("RecycleBin", string.Empty); } - set { SetValue("RecycleBin", value); } - } - - public int RecycleBinCleanupDays - { - get { return GetValueInt("RecycleBinCleanupDays", 7); } - set { SetValue("RecycleBinCleanupDays", value); } + get { return GetValueInt("HistoryCleanupDays", 365); } + set { SetValue("HistoryCleanupDays", value); } } public int RssSyncInterval @@ -202,20 +190,6 @@ namespace NzbDrone.Core.Configuration set { SetValue("RemoveFailedDownloads", value); } } - public bool CreateEmptyMovieFolders - { - get { return GetValueBoolean("CreateEmptyMovieFolders", false); } - - set { SetValue("CreateEmptyMovieFolders", value); } - } - - public bool DeleteEmptyFolders - { - get { return GetValueBoolean("DeleteEmptyFolders", false); } - - set { SetValue("DeleteEmptyFolders", value); } - } - public string DownloadClientWorkingFolders { get { return GetValue("DownloadClientWorkingFolders", "_UNPACK_|_FAILED_"); } @@ -236,76 +210,6 @@ namespace NzbDrone.Core.Configuration set { SetValue("DownloadClientHistoryLimit", value); } } - public bool SkipFreeSpaceCheckWhenImporting - { - get { return GetValueBoolean("SkipFreeSpaceCheckWhenImporting", false); } - - set { SetValue("SkipFreeSpaceCheckWhenImporting", value); } - } - - public int MinimumFreeSpaceWhenImporting - { - get { return GetValueInt("MinimumFreeSpaceWhenImporting", 100); } - - set { SetValue("MinimumFreeSpaceWhenImporting", value); } - } - - public bool CopyUsingHardlinks - { - get { return GetValueBoolean("CopyUsingHardlinks", true); } - - set { SetValue("CopyUsingHardlinks", value); } - } - - public bool EnableMediaInfo - { - get { return GetValueBoolean("EnableMediaInfo", true); } - - set { SetValue("EnableMediaInfo", value); } - } - - public bool ImportExtraFiles - { - get { return GetValueBoolean("ImportExtraFiles", false); } - - set { SetValue("ImportExtraFiles", value); } - } - - public string ExtraFileExtensions - { - get { return GetValue("ExtraFileExtensions", "srt"); } - - set { SetValue("ExtraFileExtensions", value); } - } - - public bool AutoRenameFolders - { - get { return GetValueBoolean("AutoRenameFolders", false); } - - set { SetValue("AutoRenameFolders", value); } - } - - public RescanAfterRefreshType RescanAfterRefresh - { - get { return GetValueEnum("RescanAfterRefresh", RescanAfterRefreshType.Always); } - - set { SetValue("RescanAfterRefresh", value); } - } - - public bool SetPermissionsLinux - { - get { return GetValueBoolean("SetPermissionsLinux", false); } - - set { SetValue("SetPermissionsLinux", value); } - } - - public string FileChmod - { - get { return GetValue("FileChmod", "0644"); } - - set { SetValue("FileChmod", value); } - } - public int FirstDayOfWeek { get { return GetValueInt("FirstDayOfWeek", (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek); } diff --git a/src/NzbDrone.Core/Configuration/IConfigService.cs b/src/NzbDrone.Core/Configuration/IConfigService.cs index 75397f183..1485e6de6 100644 --- a/src/NzbDrone.Core/Configuration/IConfigService.cs +++ b/src/NzbDrone.Core/Configuration/IConfigService.cs @@ -22,24 +22,8 @@ namespace NzbDrone.Core.Configuration bool AutoRedownloadFailed { get; set; } bool RemoveFailedDownloads { get; set; } - //Media Management - bool AutoUnmonitorPreviouslyDownloadedMovies { get; set; } - string RecycleBin { get; set; } - int RecycleBinCleanupDays { get; set; } - bool CreateEmptyMovieFolders { get; set; } - bool DeleteEmptyFolders { get; set; } - bool SkipFreeSpaceCheckWhenImporting { get; set; } - int MinimumFreeSpaceWhenImporting { get; set; } - bool CopyUsingHardlinks { get; set; } - bool EnableMediaInfo { get; set; } - bool ImportExtraFiles { get; set; } - string ExtraFileExtensions { get; set; } - RescanAfterRefreshType RescanAfterRefresh { get; set; } - bool AutoRenameFolders { get; set; } - - //Permissions (Media Management) - bool SetPermissionsLinux { get; set; } - string FileChmod { get; set; } + //History + int HistoryCleanupDays { get; set; } //Indexers int Retention { get; set; } diff --git a/src/NzbDrone.Core/History/CleanupHistoryCommand.cs b/src/NzbDrone.Core/History/CleanupHistoryCommand.cs new file mode 100644 index 000000000..c1741af6a --- /dev/null +++ b/src/NzbDrone.Core/History/CleanupHistoryCommand.cs @@ -0,0 +1,8 @@ +using NzbDrone.Core.Messaging.Commands; + +namespace NzbDrone.Core.History +{ + public class CleanUpHistoryCommand : Command + { + } +} diff --git a/src/NzbDrone.Core/History/History.cs b/src/NzbDrone.Core/History/History.cs index 09b9b03a7..cb9fcc8da 100644 --- a/src/NzbDrone.Core/History/History.cs +++ b/src/NzbDrone.Core/History/History.cs @@ -26,6 +26,6 @@ namespace NzbDrone.Core.History IndexerQuery = 2, IndexerRss = 3, IndexerAuth = 4, - IndexerCapabilities = 5 + IndexerInfo = 5 } } diff --git a/src/NzbDrone.Core/History/HistoryRepository.cs b/src/NzbDrone.Core/History/HistoryRepository.cs index ead83511c..83cb82e1f 100644 --- a/src/NzbDrone.Core/History/HistoryRepository.cs +++ b/src/NzbDrone.Core/History/HistoryRepository.cs @@ -15,6 +15,7 @@ namespace NzbDrone.Core.History void DeleteForIndexers(List indexerIds); History MostRecentForIndexer(int indexerId); List Since(DateTime date, HistoryEventType? eventType); + void Cleanup(int days); } public class HistoryRepository : BasicRepository, IHistoryRepository @@ -61,6 +62,11 @@ namespace NzbDrone.Core.History Delete(c => indexerIds.Contains(c.IndexerId)); } + public void Cleanup(int days) + { + Delete(c => c.Date.AddDays(days) <= DateTime.Now); + } + public History MostRecentForIndexer(int indexerId) { return Query(x => x.IndexerId == indexerId) diff --git a/src/NzbDrone.Core/History/HistoryService.cs b/src/NzbDrone.Core/History/HistoryService.cs index 85253ead9..b93475b71 100644 --- a/src/NzbDrone.Core/History/HistoryService.cs +++ b/src/NzbDrone.Core/History/HistoryService.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using NLog; +using NzbDrone.Core.Configuration; using NzbDrone.Core.Datastore; using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers.Events; @@ -29,14 +30,17 @@ namespace NzbDrone.Core.History IHandle>, IHandle, IHandle, - IHandle + IHandle, + IExecute { private readonly IHistoryRepository _historyRepository; + private readonly IConfigService _configService; private readonly Logger _logger; - public HistoryService(IHistoryRepository historyRepository, Logger logger) + public HistoryService(IHistoryRepository historyRepository, IConfigService configService, Logger logger) { _historyRepository = historyRepository; + _configService = configService; _logger = logger; } @@ -85,6 +89,23 @@ namespace NzbDrone.Core.History return _historyRepository.Since(date, eventType); } + public void Cleanup() + { + var cleanupDays = _configService.HistoryCleanupDays; + + if (cleanupDays == 0) + { + _logger.Info("Automatic cleanup of History is disabled"); + return; + } + + _logger.Info("Removing items older than {0} days from the history", cleanupDays); + + _historyRepository.Cleanup(cleanupDays); + + _logger.Debug("History has been cleaned up."); + } + public void Handle(IndexerQueryEvent message) { var history = new History @@ -171,5 +192,10 @@ namespace NzbDrone.Core.History { _historyRepository.DeleteForIndexers(new List { message.ProviderId }); } + + public void Execute(CleanUpHistoryCommand message) + { + Cleanup(); + } } } diff --git a/src/NzbDrone.Core/Jobs/TaskManager.cs b/src/NzbDrone.Core/Jobs/TaskManager.cs index 2435d67d9..7882d7fd4 100644 --- a/src/NzbDrone.Core/Jobs/TaskManager.cs +++ b/src/NzbDrone.Core/Jobs/TaskManager.cs @@ -6,6 +6,7 @@ using NzbDrone.Core.Applications; using NzbDrone.Core.Backup; using NzbDrone.Core.Configuration; using NzbDrone.Core.HealthCheck; +using NzbDrone.Core.History; using NzbDrone.Core.Housekeeping; using NzbDrone.Core.IndexerVersions; using NzbDrone.Core.Lifecycle; @@ -61,6 +62,7 @@ namespace NzbDrone.Core.Jobs new ScheduledTask { Interval = 6 * 60, TypeName = typeof(ApplicationCheckUpdateCommand).FullName }, new ScheduledTask { Interval = 6 * 60, TypeName = typeof(CheckHealthCommand).FullName }, new ScheduledTask { Interval = 24 * 60, TypeName = typeof(HousekeepingCommand).FullName }, + new ScheduledTask { Interval = 24 * 60, TypeName = typeof(CleanUpHistoryCommand).FullName }, new ScheduledTask { Interval = 24 * 60, TypeName = typeof(IndexerDefinitionUpdateCommand).FullName }, new ScheduledTask { Interval = 6 * 60, TypeName = typeof(ApplicationIndexerSyncCommand).FullName }, @@ -106,40 +108,6 @@ namespace NzbDrone.Core.Jobs return interval * 60 * 24; } - private int GetRssSyncInterval() - { - var interval = _configService.RssSyncInterval; - - if (interval > 0 && interval < 10) - { - return 10; - } - - if (interval < 0) - { - return 0; - } - - return interval; - } - - private int GetImportListSyncInterval() - { - var interval = _configService.ImportListSyncInterval; - - if (interval > 0 && interval < 10) - { - return 10; - } - - if (interval < 0) - { - return 0; - } - - return interval; - } - public void Handle(CommandExecutedEvent message) { var scheduledTask = _scheduledTaskRepository.All().SingleOrDefault(c => c.TypeName == message.Command.Body.GetType().FullName); diff --git a/src/Prowlarr.Api.V1/Config/HostConfigResource.cs b/src/Prowlarr.Api.V1/Config/HostConfigResource.cs index ca8ab32dd..568756bb4 100644 --- a/src/Prowlarr.Api.V1/Config/HostConfigResource.cs +++ b/src/Prowlarr.Api.V1/Config/HostConfigResource.cs @@ -40,6 +40,7 @@ namespace Prowlarr.Api.V1.Config public string BackupFolder { get; set; } public int BackupInterval { get; set; } public int BackupRetention { get; set; } + public int HistoryCleanupDays { get; set; } } public static class HostConfigResourceMapper @@ -80,7 +81,8 @@ namespace Prowlarr.Api.V1.Config CertificateValidation = configService.CertificateValidation, BackupFolder = configService.BackupFolder, BackupInterval = configService.BackupInterval, - BackupRetention = configService.BackupRetention + BackupRetention = configService.BackupRetention, + HistoryCleanupDays = configService.HistoryCleanupDays }; } } diff --git a/src/Prowlarr.Api.V1/Config/MediaManagementConfigController.cs b/src/Prowlarr.Api.V1/Config/MediaManagementConfigController.cs deleted file mode 100644 index ca120203b..000000000 --- a/src/Prowlarr.Api.V1/Config/MediaManagementConfigController.cs +++ /dev/null @@ -1,27 +0,0 @@ -using FluentValidation; -using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Core.Configuration; -using NzbDrone.Core.Validation; -using NzbDrone.Core.Validation.Paths; -using Prowlarr.Http; - -namespace Prowlarr.Api.V1.Config -{ - [V1ApiController("config/mediamanagement")] - public class MediaManagementConfigController : ConfigController - { - public MediaManagementConfigController(IConfigService configService, PathExistsValidator pathExistsValidator, FileChmodValidator fileChmodValidator) - : base(configService) - { - SharedValidator.RuleFor(c => c.RecycleBinCleanupDays).GreaterThanOrEqualTo(0); - SharedValidator.RuleFor(c => c.FileChmod).SetValidator(fileChmodValidator).When(c => !string.IsNullOrEmpty(c.FileChmod) && (OsInfo.IsLinux || OsInfo.IsOsx)); - SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !string.IsNullOrWhiteSpace(c.RecycleBin)); - SharedValidator.RuleFor(c => c.MinimumFreeSpaceWhenImporting).GreaterThanOrEqualTo(100); - } - - protected override MediaManagementConfigResource ToResource(IConfigService model) - { - return MediaManagementConfigResourceMapper.ToResource(model); - } - } -} diff --git a/src/Prowlarr.Api.V1/Config/MediaManagementConfigResource.cs b/src/Prowlarr.Api.V1/Config/MediaManagementConfigResource.cs deleted file mode 100644 index fa65891db..000000000 --- a/src/Prowlarr.Api.V1/Config/MediaManagementConfigResource.cs +++ /dev/null @@ -1,54 +0,0 @@ -using NzbDrone.Core.Configuration; -using Prowlarr.Http.REST; - -namespace Prowlarr.Api.V1.Config -{ - public class MediaManagementConfigResource : RestResource - { - public bool AutoUnmonitorPreviouslyDownloadedMovies { get; set; } - public string RecycleBin { get; set; } - public int RecycleBinCleanupDays { get; set; } - public bool CreateEmptyMovieFolders { get; set; } - public bool DeleteEmptyFolders { get; set; } - public RescanAfterRefreshType RescanAfterRefresh { get; set; } - public bool AutoRenameFolders { get; set; } - public bool PathsDefaultStatic { get; set; } - - public bool SetPermissionsLinux { get; set; } - public string FileChmod { get; set; } - - public bool SkipFreeSpaceCheckWhenImporting { get; set; } - public int MinimumFreeSpaceWhenImporting { get; set; } - public bool CopyUsingHardlinks { get; set; } - public bool ImportExtraFiles { get; set; } - public string ExtraFileExtensions { get; set; } - public bool EnableMediaInfo { get; set; } - } - - public static class MediaManagementConfigResourceMapper - { - public static MediaManagementConfigResource ToResource(IConfigService model) - { - return new MediaManagementConfigResource - { - AutoUnmonitorPreviouslyDownloadedMovies = model.AutoUnmonitorPreviouslyDownloadedMovies, - RecycleBin = model.RecycleBin, - RecycleBinCleanupDays = model.RecycleBinCleanupDays, - CreateEmptyMovieFolders = model.CreateEmptyMovieFolders, - DeleteEmptyFolders = model.DeleteEmptyFolders, - RescanAfterRefresh = model.RescanAfterRefresh, - AutoRenameFolders = model.AutoRenameFolders, - - SetPermissionsLinux = model.SetPermissionsLinux, - FileChmod = model.FileChmod, - - SkipFreeSpaceCheckWhenImporting = model.SkipFreeSpaceCheckWhenImporting, - MinimumFreeSpaceWhenImporting = model.MinimumFreeSpaceWhenImporting, - CopyUsingHardlinks = model.CopyUsingHardlinks, - ImportExtraFiles = model.ImportExtraFiles, - ExtraFileExtensions = model.ExtraFileExtensions, - EnableMediaInfo = model.EnableMediaInfo - }; - } - } -}