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 (
+
+ );
+}
+
+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,
+ };
+ }
+ }
+}