diff --git a/frontend/src/Movie/Details/MovieDetails.css b/frontend/src/Movie/Details/MovieDetails.css index 4bde0d661..260bcfb69 100644 --- a/frontend/src/Movie/Details/MovieDetails.css +++ b/frontend/src/Movie/Details/MovieDetails.css @@ -121,6 +121,13 @@ margin-right: 15px; } +.certification { + margin-right: 15px; + padding: 0 5px; + border: 1px solid; + border-radius: 5px; +} + .detailsLabel { composes: label from '~Components/Label.css'; diff --git a/frontend/src/Movie/Details/MovieDetails.js b/frontend/src/Movie/Details/MovieDetails.js index c753000e2..7e229761d 100644 --- a/frontend/src/Movie/Details/MovieDetails.js +++ b/frontend/src/Movie/Details/MovieDetails.js @@ -162,6 +162,7 @@ class MovieDetails extends Component { title, year, runtime, + certification, ratings, path, sizeOnDisk, @@ -329,6 +330,13 @@ class MovieDetails extends Component {
+ { + !!certification && + + {certification} + + } + { year > 0 && @@ -616,6 +624,7 @@ MovieDetails.propTypes = { title: PropTypes.string.isRequired, year: PropTypes.number.isRequired, runtime: PropTypes.number.isRequired, + certification: PropTypes.string, ratings: PropTypes.object.isRequired, path: PropTypes.string.isRequired, sizeOnDisk: PropTypes.number.isRequired, diff --git a/frontend/src/Settings/MediaManagement/Naming/NamingModal.js b/frontend/src/Settings/MediaManagement/Naming/NamingModal.js index f40c3fa50..d2c21b6a8 100644 --- a/frontend/src/Settings/MediaManagement/Naming/NamingModal.js +++ b/frontend/src/Settings/MediaManagement/Naming/NamingModal.js @@ -116,8 +116,8 @@ class NamingModal extends Component { const movieTokens = [ { token: '{Movie Title}', example: 'Movie Title!' }, { token: '{Movie CleanTitle}', example: 'Movie Title' }, - { token: '{Movie TitleThe}', example: 'Movie Title, The' } - + { token: '{Movie TitleThe}', example: 'Movie Title, The' }, + { token: '{Movie Certification}', example: 'R' } ]; const movieIdTokens = [ diff --git a/frontend/src/Settings/Metadata/MetadataSettings.js b/frontend/src/Settings/Metadata/MetadataSettings.js index 001936ab7..c51a31e7f 100644 --- a/frontend/src/Settings/Metadata/MetadataSettings.js +++ b/frontend/src/Settings/Metadata/MetadataSettings.js @@ -1,21 +1,68 @@ -import React from 'react'; +import React, { Component } from 'react'; import PageContent from 'Components/Page/PageContent'; import PageContentBodyConnector from 'Components/Page/PageContentBodyConnector'; import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector'; import MetadatasConnector from './Metadata/MetadatasConnector'; +import MetadataOptionsConnector from './Options/MetadataOptionsConnector'; -function MetadataSettings() { - return ( - - - - - - - - ); +class MetadataSettings extends Component { + + // + // Lifecycle + + constructor(props, context) { + super(props, context); + + this._saveCallback = null; + + this.state = { + isSaving: false, + hasPendingChanges: false + }; + } + + // + // Listeners + + onChildMounted = (saveCallback) => { + this._saveCallback = saveCallback; + } + + onChildStateChange = (payload) => { + this.setState(payload); + } + + onSavePress = () => { + if (this._saveCallback) { + this._saveCallback(); + } + } + + render() { + const { + isSaving, + hasPendingChanges + } = this.state; + + return ( + + + + + + + + + + ); + } } export default MetadataSettings; diff --git a/frontend/src/Settings/Metadata/Options/MetadataOptions.js b/frontend/src/Settings/Metadata/Options/MetadataOptions.js new file mode 100644 index 000000000..9f6584da1 --- /dev/null +++ b/frontend/src/Settings/Metadata/Options/MetadataOptions.js @@ -0,0 +1,66 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import { inputTypes } from 'Helpers/Props'; +import LoadingIndicator from 'Components/Loading/LoadingIndicator'; +import FieldSet from 'Components/FieldSet'; +import Form from 'Components/Form/Form'; +import FormGroup from 'Components/Form/FormGroup'; +import FormLabel from 'Components/Form/FormLabel'; +import FormInputGroup from 'Components/Form/FormInputGroup'; + +export const certificationCountryOptions = [ + { key: 'us', value: 'United States' }, + { key: 'gb', value: 'Great Britain' } +]; + +function MetadataOptions(props) { + const { + isFetching, + error, + settings, + hasSettings, + onInputChange + } = props; + + return ( +
+ { + isFetching && + + } + + { + !isFetching && error && +
Unable to load indexer options
+ } + + { + hasSettings && !isFetching && !error && +
+ + Certification Country + + + +
+ } +
+ ); +} + +MetadataOptions.propTypes = { + isFetching: PropTypes.bool.isRequired, + error: PropTypes.object, + settings: PropTypes.object.isRequired, + hasSettings: PropTypes.bool.isRequired, + onInputChange: PropTypes.func.isRequired +}; + +export default MetadataOptions; diff --git a/frontend/src/Settings/Metadata/Options/MetadataOptionsConnector.js b/frontend/src/Settings/Metadata/Options/MetadataOptionsConnector.js new file mode 100644 index 000000000..31d8e2573 --- /dev/null +++ b/frontend/src/Settings/Metadata/Options/MetadataOptionsConnector.js @@ -0,0 +1,101 @@ +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import { createSelector } from 'reselect'; +import createSettingsSectionSelector from 'Store/Selectors/createSettingsSectionSelector'; +import { fetchMetadataOptions, setMetadataOptionsValue, saveMetadataOptions } from 'Store/Actions/settingsActions'; +import { clearPendingChanges } from 'Store/Actions/baseActions'; +import MetadataOptions from './MetadataOptions'; + +const SECTION = 'metadataOptions'; + +function createMapStateToProps() { + return createSelector( + (state) => state.settings.advancedSettings, + createSettingsSectionSelector(SECTION), + (advancedSettings, sectionSettings) => { + return { + advancedSettings, + ...sectionSettings + }; + } + ); +} + +const mapDispatchToProps = { + dispatchFetchMetadataOptions: fetchMetadataOptions, + dispatchSetMetadataOptionsValue: setMetadataOptionsValue, + dispatchSaveMetadataOptions: saveMetadataOptions, + dispatchClearPendingChanges: clearPendingChanges +}; + +class MetadataOptionsConnector extends Component { + + // + // Lifecycle + + componentDidMount() { + const { + dispatchFetchMetadataOptions, + dispatchSaveMetadataOptions, + onChildMounted + } = this.props; + + dispatchFetchMetadataOptions(); + onChildMounted(dispatchSaveMetadataOptions); + } + + componentDidUpdate(prevProps) { + const { + hasPendingChanges, + isSaving, + onChildStateChange + } = this.props; + + if ( + prevProps.isSaving !== isSaving || + prevProps.hasPendingChanges !== hasPendingChanges + ) { + onChildStateChange({ + isSaving, + hasPendingChanges + }); + } + } + + componentWillUnmount() { + this.props.dispatchClearPendingChanges({ section: SECTION }); + } + + // + // Listeners + + onInputChange = ({ name, value }) => { + this.props.dispatchSetMetadataOptionsValue({ name, value }); + } + + // + // Render + + render() { + return ( + + ); + } +} + +MetadataOptionsConnector.propTypes = { + isSaving: PropTypes.bool.isRequired, + hasPendingChanges: PropTypes.bool.isRequired, + dispatchFetchMetadataOptions: PropTypes.func.isRequired, + dispatchSetMetadataOptionsValue: PropTypes.func.isRequired, + dispatchSaveMetadataOptions: PropTypes.func.isRequired, + dispatchClearPendingChanges: PropTypes.func.isRequired, + onChildMounted: PropTypes.func.isRequired, + onChildStateChange: PropTypes.func.isRequired +}; + +export default connect(createMapStateToProps, mapDispatchToProps)(MetadataOptionsConnector); diff --git a/frontend/src/Store/Actions/Settings/metadataOptions.js b/frontend/src/Store/Actions/Settings/metadataOptions.js new file mode 100644 index 000000000..3500371f4 --- /dev/null +++ b/frontend/src/Store/Actions/Settings/metadataOptions.js @@ -0,0 +1,64 @@ +import { createAction } from 'redux-actions'; +import { createThunk } from 'Store/thunks'; +import createSetSettingValueReducer from 'Store/Actions/Creators/Reducers/createSetSettingValueReducer'; +import createFetchHandler from 'Store/Actions/Creators/createFetchHandler'; +import createSaveHandler from 'Store/Actions/Creators/createSaveHandler'; + +// +// Variables + +const section = 'settings.metadataOptions'; + +// +// Actions Types + +export const FETCH_METADATA_OPTIONS = 'settings/metadataOptions/fetchMetadataOptions'; +export const SAVE_METADATA_OPTIONS = 'settings/metadataOptions/saveMetadataOptions'; +export const SET_METADATA_OPTIONS_VALUE = 'settings/metadataOptions/setMetadataOptionsValue'; + +// +// Action Creators + +export const fetchMetadataOptions = createThunk(FETCH_METADATA_OPTIONS); +export const saveMetadataOptions = createThunk(SAVE_METADATA_OPTIONS); +export const setMetadataOptionsValue = createAction(SET_METADATA_OPTIONS_VALUE, (payload) => { + return { + section, + ...payload + }; +}); + +// +// Details + +export default { + + // + // State + + defaultState: { + isFetching: false, + isPopulated: false, + error: null, + pendingChanges: {}, + isSaving: false, + saveError: null, + item: {} + }, + + // + // Action Handlers + + actionHandlers: { + [FETCH_METADATA_OPTIONS]: createFetchHandler(section, '/config/metadata'), + [SAVE_METADATA_OPTIONS]: createSaveHandler(section, '/config/metadata') + }, + + // + // Reducers + + reducers: { + [SET_METADATA_OPTIONS_VALUE]: createSetSettingValueReducer(section) + } + +}; diff --git a/frontend/src/Store/Actions/movieIndexActions.js b/frontend/src/Store/Actions/movieIndexActions.js index 7e5919791..dc2ad6a90 100644 --- a/frontend/src/Store/Actions/movieIndexActions.js +++ b/frontend/src/Store/Actions/movieIndexActions.js @@ -158,7 +158,7 @@ export const defaultState = { { name: 'certification', label: 'Certification', - isSortable: false, + isSortable: true, isVisible: false }, { @@ -320,7 +320,21 @@ export const defaultState = { { name: 'certification', label: 'Certification', - type: filterBuilderTypes.EXACT + type: filterBuilderTypes.EXACT, + optionsSelector: function(items) { + const certificationList = items.reduce((acc, movie) => { + if (movie.certification) { + acc.push({ + id: movie.certification, + name: movie.certification + }); + } + + return acc; + }, []); + + return certificationList.sort(sortByName); + } }, { name: 'tags', diff --git a/frontend/src/Store/Actions/settingsActions.js b/frontend/src/Store/Actions/settingsActions.js index 5fa96d16f..7c022bbe9 100644 --- a/frontend/src/Store/Actions/settingsActions.js +++ b/frontend/src/Store/Actions/settingsActions.js @@ -15,6 +15,7 @@ import netImportOptions from './Settings/netImportOptions'; import netImports from './Settings/netImports'; import mediaManagement from './Settings/mediaManagement'; import metadata from './Settings/metadata'; +import metadataOptions from './Settings/metadataOptions'; import naming from './Settings/naming'; import namingExamples from './Settings/namingExamples'; import notifications from './Settings/notifications'; @@ -38,6 +39,7 @@ export * from './Settings/netImportOptions'; export * from './Settings/netImports'; export * from './Settings/mediaManagement'; export * from './Settings/metadata'; +export * from './Settings/metadataOptions'; export * from './Settings/naming'; export * from './Settings/namingExamples'; export * from './Settings/notifications'; @@ -72,6 +74,7 @@ export const defaultState = { netImports: netImports.defaultState, mediaManagement: mediaManagement.defaultState, metadata: metadata.defaultState, + metadataOptions: metadataOptions.defaultState, naming: naming.defaultState, namingExamples: namingExamples.defaultState, notifications: notifications.defaultState, @@ -114,6 +117,7 @@ export const actionHandlers = handleThunks({ ...netImports.actionHandlers, ...mediaManagement.actionHandlers, ...metadata.actionHandlers, + ...metadataOptions.actionHandlers, ...naming.actionHandlers, ...namingExamples.actionHandlers, ...notifications.actionHandlers, @@ -147,6 +151,7 @@ export const reducers = createHandleActions({ ...netImports.reducers, ...mediaManagement.reducers, ...metadata.reducers, + ...metadataOptions.reducers, ...naming.reducers, ...namingExamples.reducers, ...notifications.reducers, diff --git a/src/NzbDrone.Core/Configuration/ConfigService.cs b/src/NzbDrone.Core/Configuration/ConfigService.cs index 303f83232..4f5438869 100644 --- a/src/NzbDrone.Core/Configuration/ConfigService.cs +++ b/src/NzbDrone.Core/Configuration/ConfigService.cs @@ -8,6 +8,7 @@ using NzbDrone.Common.Http.Proxy; using NzbDrone.Core.Configuration.Events; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.MetadataSource.SkyHook.Resource; using NzbDrone.Core.Parser; using NzbDrone.Core.Security; @@ -134,6 +135,13 @@ namespace NzbDrone.Core.Configuration set { SetValue("ImportExclusions", value); } } + public TMDbCountryCode CertificationCountry + { + get { return GetValueEnum("CertificationCountry", TMDbCountryCode.US); } + + set { SetValue("CertificationCountry", value); } + } + public int MaximumSize { get { return GetValueInt("MaximumSize", 0); } diff --git a/src/NzbDrone.Core/Configuration/IConfigService.cs b/src/NzbDrone.Core/Configuration/IConfigService.cs index 1fd9d9992..3404c26b2 100644 --- a/src/NzbDrone.Core/Configuration/IConfigService.cs +++ b/src/NzbDrone.Core/Configuration/IConfigService.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using NzbDrone.Common.Http.Proxy; using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.MetadataSource.SkyHook.Resource; using NzbDrone.Core.Parser; using NzbDrone.Core.Security; @@ -66,6 +67,9 @@ namespace NzbDrone.Core.Configuration string ListSyncLevel { get; set; } string ImportExclusions { get; set; } + //Metadata Provider + TMDbCountryCode CertificationCountry { get; set; } + //UI int FirstDayOfWeek { get; set; } string CalendarWeekColumnHeader { get; set; } diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs index e5eb935ac..4a7bbaa77 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -150,6 +150,11 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc uniqueId.SetAttributeValue("type", "tmdb"); details.Add(uniqueId); + if (movie.Certification.IsNotNullOrWhiteSpace()) + { + details.Add(new XElement("mpaa", movie.Certification)); + } + details.Add(new XElement("year", movie.Year)); if (movie.InCinemas.HasValue) diff --git a/src/NzbDrone.Core/Languages/LanguagesComparer.cs b/src/NzbDrone.Core/Languages/LanguagesComparer.cs index fb0cb158d..941f33e70 100644 --- a/src/NzbDrone.Core/Languages/LanguagesComparer.cs +++ b/src/NzbDrone.Core/Languages/LanguagesComparer.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace NzbDrone.Core.Languages diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/TMDbCountryCode.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/TMDbCountryCode.cs new file mode 100644 index 000000000..a1d8598a2 --- /dev/null +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/TMDbCountryCode.cs @@ -0,0 +1,8 @@ +namespace NzbDrone.Core.MetadataSource.SkyHook.Resource +{ + public enum TMDbCountryCode + { + US, + GB + } +} diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs index d1e98ddcf..0012904d6 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs @@ -8,6 +8,7 @@ using NLog; using NzbDrone.Common.Cloud; using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; +using NzbDrone.Core.Configuration; using NzbDrone.Core.Exceptions; using NzbDrone.Core.Languages; using NzbDrone.Core.MediaCover; @@ -29,30 +30,30 @@ namespace NzbDrone.Core.MetadataSource.SkyHook private readonly Logger _logger; private readonly IHttpRequestBuilderFactory _movieBuilder; - private readonly ITmdbConfigService _configService; + private readonly ITmdbConfigService _tmdbConfigService; + private readonly IConfigService _configService; private readonly IMovieService _movieService; private readonly IPreDBService _predbService; private readonly IImportExclusionsService _exclusionService; - private readonly IAlternativeTitleService _altTitleService; private readonly IRadarrAPIClient _radarrAPI; public SkyHookProxy(IHttpClient httpClient, IRadarrCloudRequestBuilder requestBuilder, - ITmdbConfigService configService, + ITmdbConfigService tmdbConfigService, + IConfigService configService, IMovieService movieService, IPreDBService predbService, IImportExclusionsService exclusionService, - IAlternativeTitleService altTitleService, IRadarrAPIClient radarrAPI, Logger logger) { _httpClient = httpClient; _movieBuilder = requestBuilder.TMDB; + _tmdbConfigService = tmdbConfigService; _configService = configService; _movieService = movieService; _predbService = predbService; _exclusionService = exclusionService; - _altTitleService = altTitleService; _radarrAPI = radarrAPI; _logger = logger; @@ -185,13 +186,9 @@ namespace NzbDrone.Core.MetadataSource.SkyHook movie.Images.AddIfNotNull(MapImage(resource.backdrop_path, MediaCoverTypes.Fanart)); movie.Runtime = resource.runtime; - //foreach(Title title in resource.alternative_titles.titles) - //{ - // movie.AlternativeTitles.Add(title.title); - //} - foreach (ReleaseDates releaseDates in resource.release_dates.results) + foreach (var releaseDates in resource.release_dates.results) { - foreach (ReleaseDate releaseDate in releaseDates.release_dates) + foreach (var releaseDate in releaseDates.release_dates) { if (releaseDate.type == 5 || releaseDate.type == 4) { @@ -209,6 +206,12 @@ namespace NzbDrone.Core.MetadataSource.SkyHook movie.PhysicalReleaseNote = releaseDate.note; } } + + // Set Certification from Theatrical Release + if (releaseDate.type == 3 && releaseDates.iso_3166_1 == _configService.CertificationCountry.ToString()) + { + movie.Certification = releaseDate.certification; + } } } @@ -216,7 +219,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook movie.Ratings.Votes = resource.vote_count; movie.Ratings.Value = (decimal)resource.vote_average; - foreach (Genre genre in resource.genres) + foreach (var genre in resource.genres) { movie.Genres.Add(genre.name); } @@ -708,7 +711,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook { if (path.IsNotNullOrWhiteSpace()) { - return _configService.GetCoverForURL(path, type); + return _tmdbConfigService.GetCoverForURL(path, type); } return null; diff --git a/src/NzbDrone.Core/Notifications/Telegram/TelegramService.cs b/src/NzbDrone.Core/Notifications/Telegram/TelegramService.cs index 3cac68688..16658f0c3 100644 --- a/src/NzbDrone.Core/Notifications/Telegram/TelegramService.cs +++ b/src/NzbDrone.Core/Notifications/Telegram/TelegramService.cs @@ -4,7 +4,6 @@ using System.Web; using FluentValidation.Results; using NLog; using NzbDrone.Common.Extensions; -using NzbDrone.Common.Http.Proxy; using NzbDrone.Common.Serializer; using NzbDrone.Core.Rest; using RestSharp; diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs index 19d69fc5f..6eb20bca5 100644 --- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -216,6 +216,7 @@ namespace NzbDrone.Core.Organizer tokenHandlers["{Movie Title}"] = m => movie.Title; tokenHandlers["{Movie CleanTitle}"] = m => CleanTitle(movie.Title); tokenHandlers["{Movie Title The}"] = m => TitleThe(movie.Title); + tokenHandlers["{Movie Certification}"] = mbox => movie.Certification; } private void AddTagsTokens(Dictionary> tokenHandlers, MovieFile movieFile) diff --git a/src/NzbDrone.Core/Parser/Augmenters/AugmentWithMediaInfo.cs b/src/NzbDrone.Core/Parser/Augmenters/AugmentWithMediaInfo.cs index 5c94dd84f..47db36369 100644 --- a/src/NzbDrone.Core/Parser/Augmenters/AugmentWithMediaInfo.cs +++ b/src/NzbDrone.Core/Parser/Augmenters/AugmentWithMediaInfo.cs @@ -1,5 +1,4 @@ using System; -using NzbDrone.Core.CustomFormats; using NzbDrone.Core.MediaFiles.MediaInfo; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Qualities; diff --git a/src/NzbDrone.Core/Qualities/Quality.cs b/src/NzbDrone.Core/Qualities/Quality.cs index a39d60a33..4a15f1bec 100644 --- a/src/NzbDrone.Core/Qualities/Quality.cs +++ b/src/NzbDrone.Core/Qualities/Quality.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using NzbDrone.Core.CustomFormats; using NzbDrone.Core.Datastore; namespace NzbDrone.Core.Qualities diff --git a/src/NzbDrone.Core/Qualities/QualityFinder.cs b/src/NzbDrone.Core/Qualities/QualityFinder.cs index 7277121b1..2c5638894 100644 --- a/src/NzbDrone.Core/Qualities/QualityFinder.cs +++ b/src/NzbDrone.Core/Qualities/QualityFinder.cs @@ -1,7 +1,6 @@ using System.Linq; using NLog; using NzbDrone.Common.Instrumentation; -using NzbDrone.Core.CustomFormats; namespace NzbDrone.Core.Qualities { diff --git a/src/Radarr.Api.V3/Config/MetadataConfigModule.cs b/src/Radarr.Api.V3/Config/MetadataConfigModule.cs new file mode 100644 index 000000000..a504e8783 --- /dev/null +++ b/src/Radarr.Api.V3/Config/MetadataConfigModule.cs @@ -0,0 +1,17 @@ +using NzbDrone.Core.Configuration; + +namespace Radarr.Api.V3.Config +{ + public class MetadataConfigModule : RadarrConfigModule + { + public MetadataConfigModule(IConfigService configService) + : base(configService) + { + } + + protected override MetadataConfigResource ToResource(IConfigService model) + { + return MetadataConfigResourceMapper.ToResource(model); + } + } +} diff --git a/src/Radarr.Api.V3/Config/MetadataConfigResource.cs b/src/Radarr.Api.V3/Config/MetadataConfigResource.cs new file mode 100644 index 000000000..e343784bc --- /dev/null +++ b/src/Radarr.Api.V3/Config/MetadataConfigResource.cs @@ -0,0 +1,22 @@ +using NzbDrone.Core.Configuration; +using NzbDrone.Core.MetadataSource.SkyHook.Resource; +using Radarr.Http.REST; + +namespace Radarr.Api.V3.Config +{ + public class MetadataConfigResource : RestResource + { + public TMDbCountryCode CertificationCountry { get; set; } + } + + public static class MetadataConfigResourceMapper + { + public static MetadataConfigResource ToResource(IConfigService model) + { + return new MetadataConfigResource + { + CertificationCountry = model.CertificationCountry, + }; + } + } +}