@@ -153,7 +149,7 @@ class DiscoverMovieFooter extends Component {
diff --git a/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosterInfo.js b/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosterInfo.js
index a1b2b2b87..4e8d97ce2 100644
--- a/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosterInfo.js
+++ b/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosterInfo.js
@@ -129,7 +129,7 @@ DiscoverMoviePosterInfo.propTypes = {
digitalRelease: PropTypes.string,
physicalRelease: PropTypes.string,
runtime: PropTypes.number,
- ratings: PropTypes.arrayOf(PropTypes.object).isRequired,
+ ratings: PropTypes.object.isRequired,
sortKey: PropTypes.string.isRequired,
showRelativeDates: PropTypes.bool.isRequired,
shortDateFormat: PropTypes.string.isRequired,
diff --git a/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.js b/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.js
index d4d30b6ba..9d6e12e4b 100644
--- a/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.js
+++ b/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.js
@@ -164,7 +164,7 @@ class DiscoverMovieRow extends Component {
key={name}
className={styles[name]}
>
- {collection ? collection.name : null }
+ {collection ? collection.title : null }
);
}
@@ -373,7 +373,7 @@ DiscoverMovieRow.propTypes = {
digitalRelease: PropTypes.string,
runtime: PropTypes.number,
genres: PropTypes.arrayOf(PropTypes.string).isRequired,
- ratings: PropTypes.arrayOf(PropTypes.object).isRequired,
+ ratings: PropTypes.object.isRequired,
certification: PropTypes.string,
collection: PropTypes.object,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
diff --git a/frontend/src/Movie/Details/MovieDetails.js b/frontend/src/Movie/Details/MovieDetails.js
index 59b9e8f94..bc9a3577f 100644
--- a/frontend/src/Movie/Details/MovieDetails.js
+++ b/frontend/src/Movie/Details/MovieDetails.js
@@ -39,7 +39,7 @@ import formatBytes from 'Utilities/Number/formatBytes';
import translate from 'Utilities/String/translate';
import selectAll from 'Utilities/Table/selectAll';
import toggleSelected from 'Utilities/Table/toggleSelected';
-import MovieCollectionConnector from './../MovieCollectionConnector';
+import MovieCollectionLabelConnector from './../MovieCollectionLabelConnector';
import MovieCastPostersConnector from './Credits/Cast/MovieCastPostersConnector';
import MovieCrewPostersConnector from './Credits/Crew/MovieCrewPostersConnector';
import MovieDetailsLinks from './MovieDetailsLinks';
@@ -583,10 +583,8 @@ class MovieDetails extends Component {
size={sizes.LARGE}
>
-
diff --git a/frontend/src/Movie/Index/ProgressBar/MovieIndexProgressBar.css b/frontend/src/Movie/Index/ProgressBar/MovieIndexProgressBar.css
index b98bb33d5..a2680291a 100644
--- a/frontend/src/Movie/Index/ProgressBar/MovieIndexProgressBar.css
+++ b/frontend/src/Movie/Index/ProgressBar/MovieIndexProgressBar.css
@@ -7,6 +7,15 @@
transition: width 200ms ease;
}
+.progressRadius {
+ composes: container from '~Components/ProgressBar.css';
+
+ border-radius: 0 0 5px 5px;
+ background-color: #5b5b5b;
+ color: $white;
+ transition: width 200ms ease;
+}
+
.progressBar {
composes: progressBar from '~Components/ProgressBar.css';
diff --git a/frontend/src/Movie/Index/ProgressBar/MovieIndexProgressBar.js b/frontend/src/Movie/Index/ProgressBar/MovieIndexProgressBar.js
index 314fb618b..888b0c05d 100644
--- a/frontend/src/Movie/Index/ProgressBar/MovieIndexProgressBar.js
+++ b/frontend/src/Movie/Index/ProgressBar/MovieIndexProgressBar.js
@@ -15,6 +15,7 @@ function MovieIndexProgressBar(props) {
isAvailable,
posterWidth,
detailedProgressBar,
+ bottomRadius,
queueStatus,
queueState
} = props;
@@ -40,7 +41,7 @@ function MovieIndexProgressBar(props) {
return (
- {collection ? collection.name : null }
+ {collection ? collection.title : null }
);
}
diff --git a/frontend/src/Movie/Index/Table/MovieIndexTable.js b/frontend/src/Movie/Index/Table/MovieIndexTable.js
index 147ba9e0b..77e77ee8b 100644
--- a/frontend/src/Movie/Index/Table/MovieIndexTable.js
+++ b/frontend/src/Movie/Index/Table/MovieIndexTable.js
@@ -65,6 +65,7 @@ class MovieIndexTable extends Component {
component={MovieIndexRow}
columns={columns}
movieId={movie.id}
+ collectionId={movie.collectionId}
qualityProfileId={movie.qualityProfileId}
isSelected={selectedState[movie.id]}
onSelectedChange={onSelectedChange}
diff --git a/frontend/src/Movie/MovieCollection.js b/frontend/src/Movie/MovieCollection.js
deleted file mode 100644
index 86e560dfb..000000000
--- a/frontend/src/Movie/MovieCollection.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-import MonitorToggleButton from 'Components/MonitorToggleButton';
-import EditImportListModalConnector from 'Settings/ImportLists/ImportLists/EditImportListModalConnector';
-import styles from './MovieCollection.css';
-
-class MovieCollection extends Component {
-
- //
- // Lifecycle
-
- constructor(props, context) {
- super(props, context);
-
- this.state = {
- hasPosterError: false,
- isEditImportListModalOpen: false
- };
- }
-
- onAddImportListPress = (monitored) => {
- if (this.props.collectionList) {
- this.props.onMonitorTogglePress(monitored);
- } else {
- this.props.onMonitorTogglePress(monitored);
- this.setState({ isEditImportListModalOpen: true });
- }
- };
-
- onEditImportListModalClose = () => {
- this.setState({ isEditImportListModalOpen: false });
- };
-
- render() {
- const {
- name,
- collectionList,
- isSaving
- } = this.props;
-
- const monitored = collectionList !== undefined && collectionList.enabled && collectionList.enableAuto;
- const importListId = collectionList ? collectionList.id : 0;
-
- return (
-
-
- {name}
-
-
- );
- }
-}
-
-MovieCollection.propTypes = {
- tmdbId: PropTypes.number.isRequired,
- name: PropTypes.string.isRequired,
- collectionList: PropTypes.object,
- isSaving: PropTypes.bool.isRequired,
- onMonitorTogglePress: PropTypes.func.isRequired
-};
-
-export default MovieCollection;
diff --git a/frontend/src/Movie/MovieCollectionConnector.js b/frontend/src/Movie/MovieCollectionConnector.js
deleted file mode 100644
index e62a380de..000000000
--- a/frontend/src/Movie/MovieCollectionConnector.js
+++ /dev/null
@@ -1,90 +0,0 @@
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-import { connect } from 'react-redux';
-import { createSelector } from 'reselect';
-import { saveImportList, selectImportListSchema, setImportListFieldValue, setImportListValue } from 'Store/Actions/settingsActions';
-import createMovieCollectionListSelector from 'Store/Selectors/createMovieCollectionListSelector';
-import createMovieSelector from 'Store/Selectors/createMovieSelector';
-import MovieCollection from './MovieCollection';
-
-function createMapStateToProps() {
- return createSelector(
- createMovieSelector(),
- createMovieCollectionListSelector(),
- (state) => state.settings.importLists,
- (movie, collectionList, importLists) => {
- const {
- monitored,
- qualityProfileId,
- minimumAvailability
- } = movie;
-
- return {
- collectionList,
- monitored,
- qualityProfileId,
- minimumAvailability,
- isSaving: importLists.isSaving
- };
- }
- );
-}
-
-const mapDispatchToProps = {
- selectImportListSchema,
- setImportListFieldValue,
- setImportListValue,
- saveImportList
-};
-
-class MovieCollectionConnector extends Component {
-
- //
- // Listeners
-
- onMonitorTogglePress = (monitored) => {
- if (this.props.collectionList) {
- this.props.setImportListValue({ name: 'enabled', value: monitored });
- this.props.setImportListValue({ name: 'enableAuto', value: monitored });
- this.props.saveImportList({ id: this.props.collectionList.id });
- } else {
- this.props.selectImportListSchema({ implementation: 'TMDbCollectionImport', presetName: undefined });
- this.props.setImportListFieldValue({ name: 'collectionId', value: this.props.tmdbId.toString() });
- this.props.setImportListValue({ name: 'enabled', value: true });
- this.props.setImportListValue({ name: 'enableAuto', value: true });
- this.props.setImportListValue({ name: 'name', value: `${this.props.name} - ${this.props.tmdbId}` });
- this.props.setImportListValue({ name: 'qualityProfileId', value: this.props.qualityProfileId });
- this.props.setImportListValue({ name: 'monitored', value: this.props.monitored });
- this.props.setImportListValue({ name: 'minimumAvailability', value: this.props.minimumAvailability });
- }
- };
-
- //
- // Render
-
- render() {
- return (
-
- );
- }
-}
-
-MovieCollectionConnector.propTypes = {
- tmdbId: PropTypes.number.isRequired,
- movieId: PropTypes.number.isRequired,
- name: PropTypes.string.isRequired,
- collectionList: PropTypes.object,
- monitored: PropTypes.bool.isRequired,
- qualityProfileId: PropTypes.number.isRequired,
- minimumAvailability: PropTypes.string.isRequired,
- isSaving: PropTypes.bool.isRequired,
- selectImportListSchema: PropTypes.func.isRequired,
- setImportListFieldValue: PropTypes.func.isRequired,
- setImportListValue: PropTypes.func.isRequired,
- saveImportList: PropTypes.func.isRequired
-};
-
-export default connect(createMapStateToProps, mapDispatchToProps)(MovieCollectionConnector);
diff --git a/frontend/src/Movie/MovieCollection.css b/frontend/src/Movie/MovieCollectionLabel.css
similarity index 100%
rename from frontend/src/Movie/MovieCollection.css
rename to frontend/src/Movie/MovieCollectionLabel.css
diff --git a/frontend/src/Movie/MovieCollectionLabel.js b/frontend/src/Movie/MovieCollectionLabel.js
new file mode 100644
index 000000000..fb071f91c
--- /dev/null
+++ b/frontend/src/Movie/MovieCollectionLabel.js
@@ -0,0 +1,46 @@
+import PropTypes from 'prop-types';
+import React, { Component } from 'react';
+import MonitorToggleButton from 'Components/MonitorToggleButton';
+import styles from './MovieCollectionLabel.css';
+
+class MovieCollectionLabel extends Component {
+
+ //
+ // Lifecycle
+
+ constructor(props, context) {
+ super(props, context);
+
+ this.state = {
+ hasPosterError: false
+ };
+ }
+
+ render() {
+ const {
+ title,
+ monitored,
+ onMonitorTogglePress
+ } = this.props;
+
+ return (
+
+
+ {title}
+
+ );
+ }
+}
+
+MovieCollectionLabel.propTypes = {
+ title: PropTypes.string.isRequired,
+ monitored: PropTypes.bool.isRequired,
+ onMonitorTogglePress: PropTypes.func.isRequired
+};
+
+export default MovieCollectionLabel;
diff --git a/frontend/src/Movie/MovieCollectionLabelConnector.js b/frontend/src/Movie/MovieCollectionLabelConnector.js
new file mode 100644
index 000000000..3d41e51e5
--- /dev/null
+++ b/frontend/src/Movie/MovieCollectionLabelConnector.js
@@ -0,0 +1,57 @@
+import PropTypes from 'prop-types';
+import React, { Component } from 'react';
+import { connect } from 'react-redux';
+import { createSelector } from 'reselect';
+import { toggleCollectionMonitored } from 'Store/Actions/movieCollectionActions';
+import MovieCollectionLabel from './MovieCollectionLabel';
+
+function createMapStateToProps() {
+ return createSelector(
+ (state, { tmdbId }) => tmdbId,
+ (state) => state.movieCollections.items,
+ (tmdbId, collections) => {
+ const collection = collections.find((movie) => movie.tmdbId === tmdbId);
+ return {
+ ...collection
+ };
+ }
+ );
+}
+
+const mapDispatchToProps = {
+ toggleCollectionMonitored
+};
+
+class MovieCollectionLabelConnector extends Component {
+
+ //
+ // Listeners
+
+ onMonitorTogglePress = (monitored) => {
+ this.props.toggleCollectionMonitored({
+ collectionId: this.props.id,
+ monitored
+ });
+ };
+
+ //
+ // Render
+
+ render() {
+ return (
+
+ );
+ }
+}
+
+MovieCollectionLabelConnector.propTypes = {
+ tmdbId: PropTypes.number.isRequired,
+ id: PropTypes.number.isRequired,
+ monitored: PropTypes.bool.isRequired,
+ toggleCollectionMonitored: PropTypes.func.isRequired
+};
+
+export default connect(createMapStateToProps, mapDispatchToProps)(MovieCollectionLabelConnector);
diff --git a/frontend/src/Settings/ImportLists/ImportLists/EditImportListModalContent.js b/frontend/src/Settings/ImportLists/ImportLists/EditImportListModalContent.js
index c3636aebb..2cc8eb7e5 100644
--- a/frontend/src/Settings/ImportLists/ImportLists/EditImportListModalContent.js
+++ b/frontend/src/Settings/ImportLists/ImportLists/EditImportListModalContent.js
@@ -42,7 +42,7 @@ function EditImportListModalContent(props) {
name,
enabled,
enableAuto,
- shouldMonitor,
+ monitor,
minimumAvailability,
qualityProfileId,
rootFolderPath,
@@ -121,31 +121,28 @@ function EditImportListModalContent(props) {
- {translate('AddMoviesMonitored')}
+ {translate('Monitor')}
- {
- shouldMonitor &&
-
- {translate('SearchOnAdd')}
+
+ {translate('SearchOnAdd')}
-
-
- }
+
+
{translate('MinimumAvailability')}
diff --git a/frontend/src/Settings/Profiles/Quality/QualityProfilesConnector.js b/frontend/src/Settings/Profiles/Quality/QualityProfilesConnector.js
index 581882ffd..354b73e70 100644
--- a/frontend/src/Settings/Profiles/Quality/QualityProfilesConnector.js
+++ b/frontend/src/Settings/Profiles/Quality/QualityProfilesConnector.js
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
+import { fetchMovieCollections } from 'Store/Actions/movieCollectionActions';
import { cloneQualityProfile, deleteQualityProfile, fetchQualityProfiles } from 'Store/Actions/settingsActions';
import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector';
import sortByName from 'Utilities/Array/sortByName';
@@ -17,7 +18,8 @@ function createMapStateToProps() {
const mapDispatchToProps = {
dispatchFetchQualityProfiles: fetchQualityProfiles,
dispatchDeleteQualityProfile: deleteQualityProfile,
- dispatchCloneQualityProfile: cloneQualityProfile
+ dispatchCloneQualityProfile: cloneQualityProfile,
+ dispatchFetchMovieCollections: fetchMovieCollections
};
class QualityProfilesConnector extends Component {
@@ -27,6 +29,7 @@ class QualityProfilesConnector extends Component {
componentDidMount() {
this.props.dispatchFetchQualityProfiles();
+ this.props.dispatchFetchMovieCollections();
}
//
@@ -57,7 +60,8 @@ class QualityProfilesConnector extends Component {
QualityProfilesConnector.propTypes = {
dispatchFetchQualityProfiles: PropTypes.func.isRequired,
dispatchDeleteQualityProfile: PropTypes.func.isRequired,
- dispatchCloneQualityProfile: PropTypes.func.isRequired
+ dispatchCloneQualityProfile: PropTypes.func.isRequired,
+ dispatchFetchMovieCollections: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(QualityProfilesConnector);
diff --git a/frontend/src/Store/Actions/addMovieActions.js b/frontend/src/Store/Actions/addMovieActions.js
index a9d1cc893..c65698e99 100644
--- a/frontend/src/Store/Actions/addMovieActions.js
+++ b/frontend/src/Store/Actions/addMovieActions.js
@@ -30,7 +30,7 @@ export const defaultState = {
defaults: {
rootFolderPath: '',
- monitor: 'true',
+ monitor: 'movieOnly',
qualityProfileId: 0,
minimumAvailability: 'announced',
searchForMovie: true,
diff --git a/frontend/src/Store/Actions/discoverMovieActions.js b/frontend/src/Store/Actions/discoverMovieActions.js
index 3b2f85b9e..ab621653b 100644
--- a/frontend/src/Store/Actions/discoverMovieActions.js
+++ b/frontend/src/Store/Actions/discoverMovieActions.js
@@ -46,7 +46,7 @@ export const defaultState = {
defaults: {
rootFolderPath: '',
- monitor: 'true',
+ monitor: 'movieOnly',
qualityProfileId: 0,
minimumAvailability: 'announced',
searchForMovie: true,
@@ -188,7 +188,7 @@ export const defaultState = {
collection: function(item) {
const { collection ={} } = item;
- return collection.name;
+ return collection.title;
},
studio: function(item) {
diff --git a/frontend/src/Store/Actions/index.js b/frontend/src/Store/Actions/index.js
index a9c3c5e35..09c373494 100644
--- a/frontend/src/Store/Actions/index.js
+++ b/frontend/src/Store/Actions/index.js
@@ -12,6 +12,7 @@ import * as importMovie from './importMovieActions';
import * as interactiveImportActions from './interactiveImportActions';
import * as movies from './movieActions';
import * as movieBlocklist from './movieBlocklistActions';
+import * as movieCollections from './movieCollectionActions';
import * as movieCredits from './movieCreditsActions';
import * as movieFiles from './movieFileActions';
import * as movieHistory from './movieHistoryActions';
@@ -50,6 +51,7 @@ export default [
rootFolders,
movies,
movieBlocklist,
+ movieCollections,
movieHistory,
movieIndex,
movieCredits,
diff --git a/frontend/src/Store/Actions/movieActions.js b/frontend/src/Store/Actions/movieActions.js
index 2e9183f89..d44c7e3b4 100644
--- a/frontend/src/Store/Actions/movieActions.js
+++ b/frontend/src/Store/Actions/movieActions.js
@@ -157,8 +157,6 @@ export const filterPredicates = {
imdbRating: function(item, filterValue, type) {
const predicate = filterTypePredicates[type];
- console.log(item.ratings);
-
const rating = item.ratings.imdb ? item.ratings.imdb.value : 0;
return predicate(rating, filterValue);
diff --git a/frontend/src/Store/Actions/movieCollectionActions.js b/frontend/src/Store/Actions/movieCollectionActions.js
new file mode 100644
index 000000000..d9c836acb
--- /dev/null
+++ b/frontend/src/Store/Actions/movieCollectionActions.js
@@ -0,0 +1,347 @@
+import _ from 'lodash';
+import { createAction } from 'redux-actions';
+import { batchActions } from 'redux-batched-actions';
+import { filterBuilderTypes, filterBuilderValueTypes, sortDirections } from 'Helpers/Props';
+import { createThunk, handleThunks } from 'Store/thunks';
+import createAjaxRequest from 'Utilities/createAjaxRequest';
+import getNewMovie from 'Utilities/Movie/getNewMovie';
+import { set, update, updateItem } from './baseActions';
+import createHandleActions from './Creators/createHandleActions';
+import createSaveProviderHandler from './Creators/createSaveProviderHandler';
+import createSetClientSideCollectionFilterReducer from './Creators/Reducers/createSetClientSideCollectionFilterReducer';
+import createSetClientSideCollectionSortReducer from './Creators/Reducers/createSetClientSideCollectionSortReducer';
+import createSetSettingValueReducer from './Creators/Reducers/createSetSettingValueReducer';
+
+//
+// Variables
+
+export const section = 'movieCollections';
+
+//
+// State
+
+export const defaultState = {
+ isFetching: false,
+ isPopulated: false,
+ error: null,
+ items: [],
+ isSaving: false,
+ saveError: null,
+ isAdding: false,
+ addError: null,
+ sortKey: 'sortTitle',
+ sortDirection: sortDirections.ASCENDING,
+ secondarySortKey: 'sortTitle',
+ secondarySortDirection: sortDirections.ASCENDING,
+ view: 'overview',
+ pendingChanges: {},
+
+ overviewOptions: {
+ detailedProgressBar: false,
+ size: 'medium',
+ showDetails: true,
+ showOverview: true
+ },
+
+ defaults: {
+ rootFolderPath: '',
+ monitor: 'movieOnly',
+ qualityProfileId: 0,
+ minimumAvailability: 'announced',
+ searchForMovie: true,
+ tags: []
+ },
+
+ selectedFilterKey: 'all',
+
+ filters: [
+ {
+ key: 'all',
+ label: 'All',
+ filters: []
+ }
+ ],
+
+ filterPredicates: {},
+
+ filterBuilderProps: [
+ {
+ name: 'title',
+ label: 'Title',
+ type: filterBuilderTypes.STRING
+ },
+ {
+ name: 'monitored',
+ label: 'Monitored',
+ type: filterBuilderTypes.EXACT,
+ valueType: filterBuilderValueTypes.BOOL
+ }
+ ]
+};
+
+export const persistState = [
+ 'movieCollections.defaults',
+ 'movieCollections.sortKey',
+ 'movieCollections.sortDirection',
+ 'movieCollections.selectedFilterKey',
+ 'movieCollections.customFilters',
+ 'movieCollections.options',
+ 'movieCollections.overviewOptions'
+];
+
+//
+// Actions Types
+
+export const FETCH_MOVIE_COLLECTIONS = 'movieCollections/fetchMovieCollections';
+export const CLEAR_MOVIE_COLLECTIONS = 'movieCollections/clearMovieCollections';
+export const SAVE_MOVIE_COLLECTION = 'movieCollections/saveMovieCollection';
+export const SAVE_MOVIE_COLLECTIONS = 'movieCollections/saveMovieCollections';
+export const SET_MOVIE_COLLECTION_VALUE = 'movieCollections/setMovieCollectionValue';
+
+export const ADD_MOVIE = 'movieCollections/addMovie';
+
+export const TOGGLE_COLLECTION_MONITORED = 'movieCollections/toggleCollectionMonitored';
+
+export const SET_MOVIE_COLLECTIONS_SORT = 'movieCollections/setMovieCollectionsSort';
+export const SET_MOVIE_COLLECTIONS_FILTER = 'movieCollections/setMovieCollectionsFilter';
+export const SET_MOVIE_COLLECTIONS_OPTION = 'movieCollections/setMovieCollectionsOption';
+export const SET_MOVIE_COLLECTIONS_OVERVIEW_OPTION = 'movieCollections/setMovieCollectionsOverviewOption';
+
+//
+// Action Creators
+
+export const fetchMovieCollections = createThunk(FETCH_MOVIE_COLLECTIONS);
+export const clearMovieCollections = createAction(CLEAR_MOVIE_COLLECTIONS);
+export const saveMovieCollection = createThunk(SAVE_MOVIE_COLLECTION);
+export const saveMovieCollections = createThunk(SAVE_MOVIE_COLLECTIONS);
+
+export const addMovie = createThunk(ADD_MOVIE);
+
+export const toggleCollectionMonitored = createThunk(TOGGLE_COLLECTION_MONITORED);
+
+export const setMovieCollectionsSort = createAction(SET_MOVIE_COLLECTIONS_SORT);
+export const setMovieCollectionsFilter = createAction(SET_MOVIE_COLLECTIONS_FILTER);
+export const setMovieCollectionsOption = createAction(SET_MOVIE_COLLECTIONS_OPTION);
+export const setMovieCollectionsOverviewOption = createAction(SET_MOVIE_COLLECTIONS_OVERVIEW_OPTION);
+
+export const setMovieCollectionValue = createAction(SET_MOVIE_COLLECTION_VALUE, (payload) => {
+ return {
+ section,
+ ...payload
+ };
+});
+
+//
+// Action Handlers
+
+export const actionHandlers = handleThunks({
+
+ [SAVE_MOVIE_COLLECTION]: createSaveProviderHandler(section, '/collection'),
+ [FETCH_MOVIE_COLLECTIONS]: function(getState, payload, dispatch) {
+ dispatch(set({ section, isFetching: true }));
+
+ const promise = createAjaxRequest({
+ url: '/collection',
+ data: payload
+ }).request;
+
+ promise.done((data) => {
+ dispatch(batchActions([
+ update({ section, data }),
+
+ set({
+ section,
+ isFetching: false,
+ isPopulated: true,
+ error: null
+ })
+ ]));
+ });
+
+ promise.fail((xhr) => {
+ dispatch(set({
+ section,
+ isFetching: false,
+ isPopulated: false,
+ error: xhr
+ }));
+ });
+ },
+
+ [ADD_MOVIE]: function(getState, payload, dispatch) {
+ dispatch(set({ section, isAdding: true }));
+
+ const tmdbId = payload.tmdbId;
+ const title = payload.title;
+
+ const newMovie = getNewMovie({ tmdbId, title }, payload);
+ newMovie.id = 0;
+
+ const promise = createAjaxRequest({
+ url: '/movie',
+ method: 'POST',
+ contentType: 'application/json',
+ data: JSON.stringify(newMovie)
+ }).request;
+
+ promise.done((data) => {
+ dispatch(batchActions([
+ updateItem({ section: 'movies', ...data }),
+
+ set({
+ section,
+ isAdding: false,
+ isAdded: true,
+ addError: null
+ })
+ ]));
+ });
+
+ promise.fail((xhr) => {
+ dispatch(set({
+ section,
+ isAdding: false,
+ isAdded: false,
+ addError: xhr
+ }));
+ });
+ },
+
+ [TOGGLE_COLLECTION_MONITORED]: (getState, payload, dispatch) => {
+ const {
+ collectionId: id,
+ monitored
+ } = payload;
+
+ const collection = _.find(getState().movieCollections.items, { id });
+
+ dispatch(updateItem({
+ id,
+ section,
+ isSaving: true
+ }));
+
+ const promise = createAjaxRequest({
+ url: `/collection/${id}`,
+ method: 'PUT',
+ data: JSON.stringify({
+ ...collection,
+ monitored
+ }),
+ dataType: 'json'
+ }).request;
+
+ promise.done((data) => {
+ dispatch(updateItem({
+ id,
+ section,
+ isSaving: false,
+ monitored
+ }));
+ });
+
+ promise.fail((xhr) => {
+ dispatch(updateItem({
+ id,
+ section,
+ isSaving: false
+ }));
+ });
+ },
+
+ [SAVE_MOVIE_COLLECTIONS]: function(getState, payload, dispatch) {
+ const {
+ collectionIds,
+ monitored,
+ monitor
+ } = payload;
+
+ const response = {};
+ const collections = [];
+
+ collectionIds.forEach((id) => {
+ const collectionToUpdate = { id };
+
+ if (payload.hasOwnProperty('monitored')) {
+ collectionToUpdate.monitored = monitored;
+ }
+
+ collections.push(collectionToUpdate);
+ });
+
+ if (payload.hasOwnProperty('monitor')) {
+ response.monitorMovies = monitor === 'monitored';
+ }
+
+ response.collections = collections;
+
+ dispatch(set({
+ section,
+ isSaving: true
+ }));
+
+ const promise = createAjaxRequest({
+ url: '/collection',
+ method: 'PUT',
+ data: JSON.stringify(response),
+ dataType: 'json'
+ }).request;
+
+ promise.done((data) => {
+ dispatch(fetchMovieCollections());
+
+ dispatch(set({
+ section,
+ isSaving: false,
+ saveError: null
+ }));
+ });
+
+ promise.fail((xhr) => {
+ dispatch(set({
+ section,
+ isSaving: false,
+ saveError: xhr
+ }));
+ });
+ }
+});
+
+//
+// Reducers
+
+export const reducers = createHandleActions({
+
+ [SET_MOVIE_COLLECTIONS_SORT]: createSetClientSideCollectionSortReducer(section),
+ [SET_MOVIE_COLLECTIONS_FILTER]: createSetClientSideCollectionFilterReducer(section),
+ [SET_MOVIE_COLLECTION_VALUE]: createSetSettingValueReducer(section),
+
+ [SET_MOVIE_COLLECTIONS_OPTION]: function(state, { payload }) {
+ const movieCollectionsOptions = state.options;
+
+ return {
+ ...state,
+ options: {
+ ...movieCollectionsOptions,
+ ...payload
+ }
+ };
+ },
+
+ [SET_MOVIE_COLLECTIONS_OVERVIEW_OPTION]: function(state, { payload }) {
+ const overviewOptions = state.overviewOptions;
+
+ return {
+ ...state,
+ overviewOptions: {
+ ...overviewOptions,
+ ...payload
+ }
+ };
+ },
+
+ [CLEAR_MOVIE_COLLECTIONS]: (state) => {
+ return Object.assign({}, state, defaultState);
+ }
+
+}, defaultState, section);
diff --git a/frontend/src/Store/Migrators/migrateMonitorToEnum.js b/frontend/src/Store/Migrators/migrateMonitorToEnum.js
new file mode 100644
index 000000000..2953b9afc
--- /dev/null
+++ b/frontend/src/Store/Migrators/migrateMonitorToEnum.js
@@ -0,0 +1,26 @@
+import get from 'lodash';
+
+export default function migrateMonitorToEnum(persistedState) {
+ const addMovie = get(persistedState, 'addMovie.defaults.monitor');
+ const discoverMovie = get(persistedState, 'discoverMovie.defaults.monitor');
+
+ if (!addMovie && !discoverMovie) {
+ return;
+ }
+
+ if (addMovie === true) {
+ persistedState.addMovie.defaults.monitor = 'movieOnly';
+ }
+
+ if (discoverMovie === true) {
+ persistedState.discoverMovie.defaults.monitor = 'movieOnly';
+ }
+
+ if (addMovie === false) {
+ persistedState.addMovie.defaults.monitor = 'none';
+ }
+
+ if (discoverMovie === false) {
+ persistedState.discoverMovie.defaults.monitor = 'none';
+ }
+}
diff --git a/frontend/src/Store/Selectors/createCollectionClientSideCollectionItemsSelector.js b/frontend/src/Store/Selectors/createCollectionClientSideCollectionItemsSelector.js
new file mode 100644
index 000000000..fd925a81c
--- /dev/null
+++ b/frontend/src/Store/Selectors/createCollectionClientSideCollectionItemsSelector.js
@@ -0,0 +1,45 @@
+import { createSelector, createSelectorCreator, defaultMemoize } from 'reselect';
+import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder';
+import createClientSideCollectionSelector from './createClientSideCollectionSelector';
+
+function createUnoptimizedSelector(uiSection) {
+ return createSelector(
+ createClientSideCollectionSelector('movieCollections', uiSection),
+ (movies) => {
+ const items = movies.items.map((s) => {
+ const {
+ id,
+ sortTitle
+ } = s;
+
+ return {
+ id,
+ sortTitle
+ };
+ });
+
+ return {
+ ...movies,
+ items
+ };
+ }
+ );
+}
+
+function movieListEqual(a, b) {
+ return hasDifferentItemsOrOrder(a, b);
+}
+
+const createMovieEqualSelector = createSelectorCreator(
+ defaultMemoize,
+ movieListEqual
+);
+
+function createCollectionClientSideCollectionItemsSelector(uiSection) {
+ return createMovieEqualSelector(
+ createUnoptimizedSelector(uiSection),
+ (movies) => movies
+ );
+}
+
+export default createCollectionClientSideCollectionItemsSelector;
diff --git a/frontend/src/Store/Selectors/createCollectionExistingMovieSelector.js b/frontend/src/Store/Selectors/createCollectionExistingMovieSelector.js
new file mode 100644
index 000000000..024d4e939
--- /dev/null
+++ b/frontend/src/Store/Selectors/createCollectionExistingMovieSelector.js
@@ -0,0 +1,14 @@
+import { createSelector } from 'reselect';
+import createAllMoviesSelector from './createAllMoviesSelector';
+
+function createCollectionExistingMovieSelector() {
+ return createSelector(
+ (state, { tmdbId }) => tmdbId,
+ createAllMoviesSelector(),
+ (tmdbId, allMovies) => {
+ return allMovies.find((movie) => movie.tmdbId === tmdbId);
+ }
+ );
+}
+
+export default createCollectionExistingMovieSelector;
diff --git a/frontend/src/Store/Selectors/createCollectionSelector.js b/frontend/src/Store/Selectors/createCollectionSelector.js
new file mode 100644
index 000000000..0b8717f96
--- /dev/null
+++ b/frontend/src/Store/Selectors/createCollectionSelector.js
@@ -0,0 +1,17 @@
+import { createSelector } from 'reselect';
+
+function createCollectionSelector() {
+ return createSelector(
+ (state, { collectionId }) => collectionId,
+ (state) => state.movieCollections.itemMap,
+ (state) => state.movieCollections.items,
+ (collectionId, itemMap, allCollections) => {
+ if (allCollections && itemMap && collectionId in itemMap) {
+ return allCollections[itemMap[collectionId]];
+ }
+ return undefined;
+ }
+ );
+}
+
+export default createCollectionSelector;
diff --git a/frontend/src/Store/Selectors/createMovieClientSideCollectionItemsSelector.js b/frontend/src/Store/Selectors/createMovieClientSideCollectionItemsSelector.js
index 755816c9d..336dd63d5 100644
--- a/frontend/src/Store/Selectors/createMovieClientSideCollectionItemsSelector.js
+++ b/frontend/src/Store/Selectors/createMovieClientSideCollectionItemsSelector.js
@@ -9,12 +9,14 @@ function createUnoptimizedSelector(uiSection) {
const items = movies.items.map((s) => {
const {
id,
- sortTitle
+ sortTitle,
+ collectionId
} = s;
return {
id,
- sortTitle
+ sortTitle,
+ collectionId
};
});
diff --git a/frontend/src/Store/Selectors/createProfileInUseSelector.js b/frontend/src/Store/Selectors/createProfileInUseSelector.js
index 7b2e4d169..a486facba 100644
--- a/frontend/src/Store/Selectors/createProfileInUseSelector.js
+++ b/frontend/src/Store/Selectors/createProfileInUseSelector.js
@@ -7,12 +7,13 @@ function createProfileInUseSelector(profileProp) {
(state, { id }) => id,
createAllMoviesSelector(),
(state) => state.settings.importLists.items,
- (id, movies, lists) => {
+ (state) => state.movieCollections.items,
+ (id, movies, lists, collections) => {
if (!id) {
return false;
}
- if (_.some(movies, { [profileProp]: id }) || _.some(lists, { [profileProp]: id })) {
+ if (_.some(movies, { [profileProp]: id }) || _.some(lists, { [profileProp]: id }) || _.some(collections, { [profileProp]: id })) {
return true;
}
diff --git a/frontend/src/Store/scrollPositions.js b/frontend/src/Store/scrollPositions.js
index 99a558b4d..74983dcbc 100644
--- a/frontend/src/Store/scrollPositions.js
+++ b/frontend/src/Store/scrollPositions.js
@@ -1,6 +1,7 @@
const scrollPositions = {
movieIndex: 0,
- discoverMovie: 0
+ discoverMovie: 0,
+ movieCollections: 0
};
export default scrollPositions;
diff --git a/frontend/src/Utilities/Movie/getNewMovie.js b/frontend/src/Utilities/Movie/getNewMovie.js
index e9dc84489..387fae616 100644
--- a/frontend/src/Utilities/Movie/getNewMovie.js
+++ b/frontend/src/Utilities/Movie/getNewMovie.js
@@ -10,11 +10,12 @@ function getNewMovie(movie, payload) {
} = payload;
const addOptions = {
+ monitor,
searchForMovie
};
movie.addOptions = addOptions;
- movie.monitored = monitor === 'true';
+ movie.monitored = monitor !== 'none';
movie.qualityProfileId = qualityProfileId;
movie.minimumAvailability = minimumAvailability;
movie.rootFolderPath = rootFolderPath;
diff --git a/frontend/src/Utilities/Movie/monitorOptions.js b/frontend/src/Utilities/Movie/monitorOptions.js
new file mode 100644
index 000000000..db2c519b8
--- /dev/null
+++ b/frontend/src/Utilities/Movie/monitorOptions.js
@@ -0,0 +1,9 @@
+import translate from 'Utilities/String/translate';
+
+const monitorOptions = [
+ { key: 'movieOnly', value: translate('MovieOnly') },
+ { key: 'movieAndCollection', value: translate('MovieAndCollection') },
+ { key: 'none', value: translate('None') }
+];
+
+export default monitorOptions;
diff --git a/package.json b/package.json
index d2f91f2b9..c23bcced9 100644
--- a/package.json
+++ b/package.json
@@ -62,6 +62,8 @@
"react-document-title": "2.0.3",
"react-dom": "17.0.2",
"react-focus-lock": "2.5.0",
+ "react-slick": "0.28.1",
+ "slick-carousel": "1.8.1",
"react-google-recaptcha": "2.1.0",
"react-lazyload": "3.2.0",
"react-measure": "1.4.7",
diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/208_collectionsFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/208_collectionsFixture.cs
new file mode 100644
index 000000000..9678b89cb
--- /dev/null
+++ b/src/NzbDrone.Core.Test/Datastore/Migration/208_collectionsFixture.cs
@@ -0,0 +1,293 @@
+using System;
+using System.Linq;
+using FluentAssertions;
+using NUnit.Framework;
+using NzbDrone.Common.Serializer;
+using NzbDrone.Core.Datastore.Migration;
+using NzbDrone.Core.Test.Framework;
+
+namespace NzbDrone.Core.Test.Datastore.Migration
+{
+ [TestFixture]
+ public class collectionsFixture : MigrationTest
+ {
+ [Test]
+ public void should_add_collection_from_movie_and_link_back_to_movie()
+ {
+ var db = WithMigrationTestDb(c =>
+ {
+ c.Insert.IntoTable("Movies").Row(new
+ {
+ Monitored = true,
+ MinimumAvailability = 4,
+ ProfileId = 1,
+ MovieFileId = 0,
+ MovieMetadataId = 1,
+ Path = string.Format("/Movies/{0}", "Title"),
+ });
+
+ c.Insert.IntoTable("MovieMetadata").Row(new
+ {
+ Title = "Title",
+ CleanTitle = "CleanTitle",
+ Status = 3,
+ Images = new[] { new { CoverType = "Poster" } }.ToJson(),
+ Recommendations = new[] { 1 }.ToJson(),
+ Runtime = 90,
+ OriginalTitle = "Title",
+ CleanOriginalTitle = "CleanTitle",
+ OriginalLanguage = 1,
+ TmdbId = 132456,
+ Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
+ LastInfoSync = DateTime.UtcNow,
+ });
+ });
+
+ var collections = db.Query("SELECT \"Id\", \"Title\", \"TmdbId\", \"Monitored\" FROM \"Collections\"");
+
+ collections.Should().HaveCount(1);
+ collections.First().TmdbId.Should().Be(11);
+ collections.First().Title.Should().Be("Some Collection");
+ collections.First().Monitored.Should().BeFalse();
+
+ var movies = db.Query("SELECT \"Id\", \"CollectionTmdbId\" FROM \"MovieMetadata\"");
+
+ movies.Should().HaveCount(1);
+ movies.First().CollectionTmdbId.Should().Be(collections.First().TmdbId);
+ }
+
+ [Test]
+ public void should_not_duplicate_collection()
+ {
+ var db = WithMigrationTestDb(c =>
+ {
+ c.Insert.IntoTable("Movies").Row(new
+ {
+ Monitored = true,
+ MinimumAvailability = 4,
+ ProfileId = 1,
+ MovieFileId = 0,
+ MovieMetadataId = 1,
+ Path = string.Format("/Movies/{0}", "Title"),
+ });
+
+ c.Insert.IntoTable("MovieMetadata").Row(new
+ {
+ Title = "Title",
+ CleanTitle = "CleanTitle",
+ Status = 3,
+ Images = new[] { new { CoverType = "Poster" } }.ToJson(),
+ Recommendations = new[] { 1 }.ToJson(),
+ Runtime = 90,
+ OriginalTitle = "Title",
+ CleanOriginalTitle = "CleanTitle",
+ OriginalLanguage = 1,
+ TmdbId = 132456,
+ Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
+ LastInfoSync = DateTime.UtcNow,
+ });
+
+ c.Insert.IntoTable("Movies").Row(new
+ {
+ Monitored = true,
+ MinimumAvailability = 4,
+ ProfileId = 1,
+ MovieFileId = 0,
+ MovieMetadataId = 2,
+ Path = string.Format("/Movies/{0}", "Title"),
+ });
+
+ c.Insert.IntoTable("MovieMetadata").Row(new
+ {
+ Title = "Title2",
+ CleanTitle = "CleanTitle2",
+ Status = 3,
+ Images = new[] { new { CoverType = "Poster" } }.ToJson(),
+ Recommendations = new[] { 1 }.ToJson(),
+ Runtime = 90,
+ OriginalTitle = "Title2",
+ CleanOriginalTitle = "CleanTitle2",
+ OriginalLanguage = 1,
+ TmdbId = 132457,
+ Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
+ LastInfoSync = DateTime.UtcNow,
+ });
+ });
+
+ var collections = db.Query("SELECT \"Id\", \"Title\", \"TmdbId\", \"Monitored\" FROM \"Collections\"");
+
+ collections.Should().HaveCount(1);
+ collections.First().TmdbId.Should().Be(11);
+ collections.First().Title.Should().Be("Some Collection");
+ collections.First().Monitored.Should().BeFalse();
+ }
+
+ [Test]
+ public void should_migrate_true_monitor_setting_on_lists()
+ {
+ var db = WithMigrationTestDb(c =>
+ {
+ c.Insert.IntoTable("ImportLists").Row(new
+ {
+ Enabled = true,
+ EnableAuto = true,
+ RootFolderPath = "D:\\Movies",
+ ProfileId = 1,
+ MinimumAvailability = 4,
+ ShouldMonitor = true,
+ Name = "IMDB List",
+ Implementation = "RadarrLists",
+ Settings = new RadarrListSettings169
+ {
+ APIURL = "https://api.radarr.video/v2",
+ Path = "/imdb/list?listId=ls000199717",
+ }.ToJson(),
+ ConfigContract = "RadarrSettings"
+ });
+ });
+
+ var items = db.Query("SELECT \"Id\", \"Monitor\" FROM \"ImportLists\"");
+
+ items.Should().HaveCount(1);
+ items.First().Monitor.Should().Be(0);
+ }
+
+ [Test]
+ public void should_migrate_false_monitor_setting_on_lists()
+ {
+ var db = WithMigrationTestDb(c =>
+ {
+ c.Insert.IntoTable("ImportLists").Row(new
+ {
+ Enabled = true,
+ EnableAuto = true,
+ RootFolderPath = "D:\\Movies",
+ ProfileId = 1,
+ MinimumAvailability = 4,
+ ShouldMonitor = false,
+ Name = "IMDB List",
+ Implementation = "RadarrLists",
+ Settings = new RadarrListSettings169
+ {
+ APIURL = "https://api.radarr.video/v2",
+ Path = "/imdb/list?listId=ls000199717",
+ }.ToJson(),
+ ConfigContract = "RadarrSettings"
+ });
+ });
+
+ var items = db.Query("SELECT \"Id\", \"Monitor\" FROM \"ImportLists\"");
+
+ items.Should().HaveCount(1);
+ items.First().Monitor.Should().Be(2);
+ }
+
+ [Test]
+ public void should_purge_tmdb_collection_lists()
+ {
+ var db = WithMigrationTestDb(c =>
+ {
+ c.Insert.IntoTable("ImportLists").Row(new
+ {
+ Enabled = true,
+ EnableAuto = true,
+ RootFolderPath = "D:\\Movies",
+ ProfileId = 1,
+ MinimumAvailability = 4,
+ ShouldMonitor = false,
+ Name = "IMDB List",
+ Implementation = "TMDbCollectionImport",
+ Settings = new TmdbCollectionListSettings207
+ {
+ CollectionId = "11"
+ }.ToJson(),
+ ConfigContract = "TMDbCollectionSettings"
+ });
+ });
+
+ var items = db.Query("SELECT \"Id\", \"Monitor\" FROM \"ImportLists\"");
+
+ items.Should().HaveCount(0);
+ }
+
+ [Test]
+ public void should_monitor_new_collection_if_list_enabled_and_auto()
+ {
+ var db = WithMigrationTestDb(c =>
+ {
+ c.Insert.IntoTable("Movies").Row(new
+ {
+ Monitored = true,
+ MinimumAvailability = 4,
+ ProfileId = 1,
+ MovieFileId = 0,
+ MovieMetadataId = 1,
+ Path = string.Format("/Movies/{0}", "Title"),
+ });
+
+ c.Insert.IntoTable("MovieMetadata").Row(new
+ {
+ Title = "Title",
+ CleanTitle = "CleanTitle",
+ Status = 3,
+ Images = new[] { new { CoverType = "Poster" } }.ToJson(),
+ Recommendations = new[] { 1 }.ToJson(),
+ Runtime = 90,
+ OriginalTitle = "Title",
+ CleanOriginalTitle = "CleanTitle",
+ OriginalLanguage = 1,
+ TmdbId = 132456,
+ Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
+ LastInfoSync = DateTime.UtcNow,
+ });
+
+ c.Insert.IntoTable("ImportLists").Row(new
+ {
+ Enabled = true,
+ EnableAuto = true,
+ RootFolderPath = "D:\\Movies",
+ ProfileId = 1,
+ MinimumAvailability = 4,
+ ShouldMonitor = false,
+ Name = "IMDB List",
+ Implementation = "TMDbCollectionImport",
+ Settings = new TmdbCollectionListSettings207
+ {
+ CollectionId = "11"
+ }.ToJson(),
+ ConfigContract = "TMDbCollectionSettings"
+ });
+ });
+
+ var items = db.Query("SELECT \"Id\", \"Monitored\" FROM \"Collections\"");
+
+ items.Should().HaveCount(1);
+ items.First().Monitored.Should().BeTrue();
+ }
+ }
+
+ public class Collection208
+ {
+ public int Id { get; set; }
+ public int TmdbId { get; set; }
+ public string Title { get; set; }
+ public bool Monitored { get; set; }
+ }
+
+ public class Movie208
+ {
+ public int Id { get; set; }
+ public int CollectionTmdbId { get; set; }
+ }
+
+ public class ListDefinition208
+ {
+ public int Id { get; set; }
+ public int Monitor { get; set; }
+ }
+
+ public class TmdbCollectionListSettings207
+ {
+ public string CollectionId { get; set; }
+ }
+}
diff --git a/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedCollectionsFixture.cs b/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedCollectionsFixture.cs
new file mode 100644
index 000000000..79ffe3a84
--- /dev/null
+++ b/src/NzbDrone.Core.Test/Housekeeping/Housekeepers/CleanupOrphanedCollectionsFixture.cs
@@ -0,0 +1,47 @@
+using FizzWare.NBuilder;
+using FluentAssertions;
+using NUnit.Framework;
+using NzbDrone.Core.Housekeeping.Housekeepers;
+using NzbDrone.Core.Movies;
+using NzbDrone.Core.Movies.Collections;
+using NzbDrone.Core.Test.Framework;
+
+namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
+{
+ [TestFixture]
+ public class CleanupOrphanedCollectionsFixture : DbTest
+ {
+ [Test]
+ public void should_delete_orphaned_collection_item()
+ {
+ var collection = Builder.CreateNew()
+ .With(h => h.Id = 3)
+ .With(h => h.TmdbId = 123456)
+ .With(h => h.Title = "Some Credit")
+ .BuildNew();
+
+ Db.Insert(collection);
+ Subject.Clean();
+ AllStoredModels.Should().BeEmpty();
+ }
+
+ [Test]
+ public void should_not_delete_unorphaned_collection_items()
+ {
+ var collection = Builder.CreateNew()
+ .With(h => h.Id = 3)
+ .With(h => h.TmdbId = 123456)
+ .With(h => h.Title = "Some Credit")
+ .BuildNew();
+
+ Db.Insert(collection);
+
+ var movie = Builder.CreateNew().With(m => m.CollectionTmdbId = collection.TmdbId).BuildNew();
+
+ Db.Insert(movie);
+
+ Subject.Clean();
+ AllStoredModels.Should().HaveCount(1);
+ }
+ }
+}
diff --git a/src/NzbDrone.Core.Test/MovieTests/AddMovieFixture.cs b/src/NzbDrone.Core.Test/MovieTests/AddMovieFixture.cs
index 1652da06c..a97d6196b 100644
--- a/src/NzbDrone.Core.Test/MovieTests/AddMovieFixture.cs
+++ b/src/NzbDrone.Core.Test/MovieTests/AddMovieFixture.cs
@@ -27,6 +27,8 @@ namespace NzbDrone.Core.Test.MovieTests
{
_fakeMovie = Builder
.CreateNew()
+ .With(x => x.CollectionTitle = null)
+ .With(x => x.CollectionTmdbId = 0)
.Build();
}
diff --git a/src/NzbDrone.Core.Test/MovieTests/RefreshMovieServiceFixture.cs b/src/NzbDrone.Core.Test/MovieTests/RefreshMovieServiceFixture.cs
index 8acb3706c..d1ee7fa67 100644
--- a/src/NzbDrone.Core.Test/MovieTests/RefreshMovieServiceFixture.cs
+++ b/src/NzbDrone.Core.Test/MovieTests/RefreshMovieServiceFixture.cs
@@ -8,6 +8,7 @@ using NzbDrone.Common.Extensions;
using NzbDrone.Core.Exceptions;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Movies;
+using NzbDrone.Core.Movies.Collections;
using NzbDrone.Core.Movies.Commands;
using NzbDrone.Core.Movies.Credits;
using NzbDrone.Core.Test.Framework;
@@ -19,6 +20,7 @@ namespace NzbDrone.Core.Test.MovieTests
public class RefreshMovieServiceFixture : CoreTest
{
private MovieMetadata _movie;
+ private MovieCollection _movieCollection;
private Movie _existingMovie;
[SetUp]
@@ -28,6 +30,9 @@ namespace NzbDrone.Core.Test.MovieTests
.With(s => s.Status = MovieStatusType.Released)
.Build();
+ _movieCollection = Builder.CreateNew()
+ .Build();
+
_existingMovie = Builder.CreateNew()
.With(s => s.MovieMetadata.Value.Status = MovieStatusType.Released)
.Build();
@@ -40,6 +45,10 @@ namespace NzbDrone.Core.Test.MovieTests
.Setup(s => s.Get(_movie.Id))
.Returns(_movie);
+ Mocker.GetMock()
+ .Setup(v => v.AddMovieCollection(It.IsAny()))
+ .Returns(_movieCollection);
+
Mocker.GetMock()
.Setup(s => s.GetMovieInfo(It.IsAny()))
.Callback((i) => { throw new MovieNotFoundException(i); });
diff --git a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/FileNameBuilderFixture.cs b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/FileNameBuilderFixture.cs
index 3ac3761ce..42bd3a643 100644
--- a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/FileNameBuilderFixture.cs
+++ b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/FileNameBuilderFixture.cs
@@ -12,6 +12,7 @@ using NzbDrone.Core.Languages;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MediaFiles.MediaInfo;
using NzbDrone.Core.Movies;
+using NzbDrone.Core.Movies.Collections;
using NzbDrone.Core.Movies.Translations;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Qualities;
@@ -226,7 +227,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
public void should_replace_movie_collection()
{
_namingConfig.StandardMovieFormat = "{Movie Collection}";
- _movie.MovieMetadata.Value.Collection = new MovieCollection { Name = "South Part Collection" };
+ _movie.MovieMetadata.Value.CollectionTitle = "South Part Collection";
Subject.BuildFileName(_movie, _movieFile)
.Should().Be("South Part Collection");
diff --git a/src/NzbDrone.Core.Test/Profiles/ProfileServiceFixture.cs b/src/NzbDrone.Core.Test/Profiles/ProfileServiceFixture.cs
index b4739718b..583730671 100644
--- a/src/NzbDrone.Core.Test/Profiles/ProfileServiceFixture.cs
+++ b/src/NzbDrone.Core.Test/Profiles/ProfileServiceFixture.cs
@@ -9,6 +9,7 @@ using NzbDrone.Core.ImportLists;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Movies;
+using NzbDrone.Core.Movies.Collections;
using NzbDrone.Core.Profiles;
using NzbDrone.Core.Test.CustomFormats;
using NzbDrone.Core.Test.Framework;
@@ -90,6 +91,33 @@ namespace NzbDrone.Core.Test.Profiles
Mocker.GetMock().Verify(c => c.Delete(It.IsAny()), Times.Never());
}
+ [Test]
+ public void should_not_be_able_to_delete_profile_if_assigned_to_collection()
+ {
+ var movieList = Builder.CreateListOfSize(3)
+ .All()
+ .With(c => c.ProfileId = 1)
+ .Build().ToList();
+
+ var importList = Builder.CreateListOfSize(3)
+ .Random(1)
+ .With(c => c.ProfileId = 1)
+ .Build().ToList();
+
+ var collectionList = Builder.CreateListOfSize(3)
+ .All()
+ .With(c => c.QualityProfileId = 2)
+ .Build().ToList();
+
+ Mocker.GetMock().Setup(c => c.GetAllMovies()).Returns(movieList);
+ Mocker.GetMock().Setup(c => c.All()).Returns(importList);
+ Mocker.GetMock().Setup(c => c.GetAllCollections()).Returns(collectionList);
+
+ Assert.Throws(() => Subject.Delete(2));
+
+ Mocker.GetMock().Verify(c => c.Delete(It.IsAny()), Times.Never());
+ }
+
[Test]
public void should_delete_profile_if_not_assigned_to_movie_or_list()
{
@@ -103,8 +131,14 @@ namespace NzbDrone.Core.Test.Profiles
.With(c => c.ProfileId = 2)
.Build().ToList();
+ var collectionList = Builder.CreateListOfSize(3)
+ .All()
+ .With(c => c.QualityProfileId = 2)
+ .Build().ToList();
+
Mocker.GetMock().Setup(c => c.GetAllMovies()).Returns(movieList);
Mocker.GetMock().Setup(c => c.All()).Returns(importList);
+ Mocker.GetMock().Setup(c => c.GetAllCollections()).Returns(collectionList);
Subject.Delete(1);
diff --git a/src/NzbDrone.Core/Configuration/ConfigService.cs b/src/NzbDrone.Core/Configuration/ConfigService.cs
index 8dc2b746e..277b60a16 100644
--- a/src/NzbDrone.Core/Configuration/ConfigService.cs
+++ b/src/NzbDrone.Core/Configuration/ConfigService.cs
@@ -5,7 +5,6 @@ using System.Linq;
using NLog;
using NzbDrone.Common.EnsureThat;
using NzbDrone.Common.Http.Proxy;
-using NzbDrone.Core.Configuration;
using NzbDrone.Core.Configuration.Events;
using NzbDrone.Core.Languages;
using NzbDrone.Core.MediaFiles;
diff --git a/src/NzbDrone.Core/Configuration/IConfigService.cs b/src/NzbDrone.Core/Configuration/IConfigService.cs
index dade3eef1..c51b27722 100644
--- a/src/NzbDrone.Core/Configuration/IConfigService.cs
+++ b/src/NzbDrone.Core/Configuration/IConfigService.cs
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using NzbDrone.Common.Http.Proxy;
-using NzbDrone.Core.Configuration;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
using NzbDrone.Core.Qualities;
diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/IndexerFlagSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/IndexerFlagSpecification.cs
index 29683ebd5..7aac93c54 100644
--- a/src/NzbDrone.Core/CustomFormats/Specifications/IndexerFlagSpecification.cs
+++ b/src/NzbDrone.Core/CustomFormats/Specifications/IndexerFlagSpecification.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Parser.Model;
diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/ReleaseTitleSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/ReleaseTitleSpecification.cs
index e031dd007..af3202c9f 100644
--- a/src/NzbDrone.Core/CustomFormats/Specifications/ReleaseTitleSpecification.cs
+++ b/src/NzbDrone.Core/CustomFormats/Specifications/ReleaseTitleSpecification.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using NzbDrone.Common.Extensions;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.CustomFormats
diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/SizeSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/SizeSpecification.cs
index 532087b6c..1124783fb 100644
--- a/src/NzbDrone.Core/CustomFormats/Specifications/SizeSpecification.cs
+++ b/src/NzbDrone.Core/CustomFormats/Specifications/SizeSpecification.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Parser.Model;
diff --git a/src/NzbDrone.Core/Datastore/LazyLoaded.cs b/src/NzbDrone.Core/Datastore/LazyLoaded.cs
index 91ff44c82..288726efb 100644
--- a/src/NzbDrone.Core/Datastore/LazyLoaded.cs
+++ b/src/NzbDrone.Core/Datastore/LazyLoaded.cs
@@ -1,4 +1,5 @@
-using System;
+using System;
+using System.Text.Json.Serialization;
using NLog;
using NzbDrone.Common.Instrumentation;
@@ -15,6 +16,7 @@ namespace NzbDrone.Core.Datastore
/// Allows a field to be lazy loaded.
///
///
+ [JsonConverter(typeof(LazyLoadedConverterFactory))]
public class LazyLoaded : ILazyLoaded
{
protected TChild _value;
@@ -62,11 +64,6 @@ namespace NzbDrone.Core.Datastore
{
return MemberwiseClone();
}
-
- public bool ShouldSerializeValue()
- {
- return IsLoaded;
- }
}
///
diff --git a/src/NzbDrone.Core/Datastore/LazyLoadedConverterFactory.cs b/src/NzbDrone.Core/Datastore/LazyLoadedConverterFactory.cs
new file mode 100644
index 000000000..4e02ef794
--- /dev/null
+++ b/src/NzbDrone.Core/Datastore/LazyLoadedConverterFactory.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Reflection;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace NzbDrone.Core.Datastore
+{
+ public class LazyLoadedConverterFactory : JsonConverterFactory
+ {
+ public override bool CanConvert(Type typeToConvert)
+ {
+ if (!typeToConvert.IsGenericType)
+ {
+ return false;
+ }
+
+ return typeToConvert.GetGenericTypeDefinition() == typeof(LazyLoaded<>);
+ }
+
+ public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options)
+ {
+ var childType = type.GetGenericArguments()[0];
+
+ return (JsonConverter)Activator.CreateInstance(
+ typeof(LazyLoadedConverter<>).MakeGenericType(childType),
+ BindingFlags.Instance | BindingFlags.Public,
+ binder: null,
+ args: new object[] { options },
+ culture: null);
+ }
+
+ private class LazyLoadedConverter : JsonConverter>
+ {
+ private readonly JsonConverter _childConverter;
+ private readonly Type _childType;
+
+ public LazyLoadedConverter(JsonSerializerOptions options)
+ {
+ // For performance, use the existing converter if available.
+ _childConverter = (JsonConverter)options
+ .GetConverter(typeof(TChild));
+
+ // Cache the type.
+ _childType = typeof(TChild);
+ }
+
+ public override LazyLoaded Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ TChild value;
+ if (_childConverter != null)
+ {
+ reader.Read();
+ value = _childConverter.Read(ref reader, _childType, options);
+ }
+ else
+ {
+ value = JsonSerializer.Deserialize(ref reader, options);
+ }
+
+ if (value != null)
+ {
+ return new LazyLoaded(value);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public override void Write(Utf8JsonWriter writer, LazyLoaded value, JsonSerializerOptions options)
+ {
+ if (value.IsLoaded)
+ {
+ if (_childConverter != null)
+ {
+ _childConverter.Write(writer, value.Value, options);
+ }
+ else
+ {
+ JsonSerializer.Serialize(writer, value.Value, options);
+ }
+ }
+ else
+ {
+ writer.WriteNullValue();
+ }
+ }
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Datastore/Migration/165_remove_custom_formats_from_quality_model.cs b/src/NzbDrone.Core/Datastore/Migration/165_remove_custom_formats_from_quality_model.cs
index 236aac66e..4dc4a2a13 100644
--- a/src/NzbDrone.Core/Datastore/Migration/165_remove_custom_formats_from_quality_model.cs
+++ b/src/NzbDrone.Core/Datastore/Migration/165_remove_custom_formats_from_quality_model.cs
@@ -4,7 +4,6 @@ using System.Data;
using System.Linq;
using Dapper;
using FluentMigrator;
-using NzbDrone.Common.Extensions;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Datastore.Converters;
using NzbDrone.Core.Datastore.Migration.Framework;
diff --git a/src/NzbDrone.Core/Datastore/Migration/189_add_update_history.cs b/src/NzbDrone.Core/Datastore/Migration/189_add_update_history.cs
index 111a7e1c9..cc70f0e3a 100644
--- a/src/NzbDrone.Core/Datastore/Migration/189_add_update_history.cs
+++ b/src/NzbDrone.Core/Datastore/Migration/189_add_update_history.cs
@@ -1,6 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Data;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
diff --git a/src/NzbDrone.Core/Datastore/Migration/190_update_awesome_hd_link.cs b/src/NzbDrone.Core/Datastore/Migration/190_update_awesome_hd_link.cs
index 42029d793..d1c228488 100644
--- a/src/NzbDrone.Core/Datastore/Migration/190_update_awesome_hd_link.cs
+++ b/src/NzbDrone.Core/Datastore/Migration/190_update_awesome_hd_link.cs
@@ -1,5 +1,4 @@
using FluentMigrator;
-using Newtonsoft.Json.Linq;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
diff --git a/src/NzbDrone.Core/Datastore/Migration/195_update_notifiarr.cs b/src/NzbDrone.Core/Datastore/Migration/195_update_notifiarr.cs
index a8cccfd6a..a773cedce 100644
--- a/src/NzbDrone.Core/Datastore/Migration/195_update_notifiarr.cs
+++ b/src/NzbDrone.Core/Datastore/Migration/195_update_notifiarr.cs
@@ -1,5 +1,4 @@
using FluentMigrator;
-using Newtonsoft.Json.Linq;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
diff --git a/src/NzbDrone.Core/Datastore/Migration/200_cdh_per_downloadclient.cs b/src/NzbDrone.Core/Datastore/Migration/200_cdh_per_downloadclient.cs
index 68bbdd70a..cf80cc465 100644
--- a/src/NzbDrone.Core/Datastore/Migration/200_cdh_per_downloadclient.cs
+++ b/src/NzbDrone.Core/Datastore/Migration/200_cdh_per_downloadclient.cs
@@ -1,8 +1,5 @@
using System.Data;
-using System.Linq;
using FluentMigrator;
-using Newtonsoft.Json.Linq;
-using NzbDrone.Common.Serializer;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
diff --git a/src/NzbDrone.Core/Datastore/Migration/208_collections.cs b/src/NzbDrone.Core/Datastore/Migration/208_collections.cs
new file mode 100644
index 000000000..9d5f8cd05
--- /dev/null
+++ b/src/NzbDrone.Core/Datastore/Migration/208_collections.cs
@@ -0,0 +1,265 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using Dapper;
+using FluentMigrator;
+using NzbDrone.Common.Extensions;
+using NzbDrone.Common.Serializer;
+using NzbDrone.Core.Datastore.Migration.Framework;
+using NzbDrone.Core.Parser;
+
+namespace NzbDrone.Core.Datastore.Migration
+{
+ [Migration(208)]
+ public class collections : NzbDroneMigrationBase
+ {
+ protected override void MainDbUpgrade()
+ {
+ Create.TableForModel("Collections")
+ .WithColumn("TmdbId").AsInt32().Unique()
+ .WithColumn("QualityProfileId").AsInt32()
+ .WithColumn("RootFolderPath").AsString()
+ .WithColumn("MinimumAvailability").AsInt32()
+ .WithColumn("SearchOnAdd").AsBoolean()
+ .WithColumn("Title").AsString()
+ .WithColumn("SortTitle").AsString().Nullable()
+ .WithColumn("CleanTitle").AsString()
+ .WithColumn("Overview").AsString().Nullable()
+ .WithColumn("Images").AsString().WithDefaultValue("[]")
+ .WithColumn("Monitored").AsBoolean().WithDefaultValue(false)
+ .WithColumn("LastInfoSync").AsDateTime().Nullable()
+ .WithColumn("Added").AsDateTime().Nullable();
+
+ Alter.Table("MovieMetadata").AddColumn("CollectionTmdbId").AsInt32().Nullable()
+ .AddColumn("CollectionTitle").AsString().Nullable();
+
+ Alter.Table("ImportLists").AddColumn("Monitor").AsInt32().Nullable();
+
+ Execute.WithConnection(MigrateCollections);
+ Execute.WithConnection(MigrateCollectionMonitorStatus);
+ Execute.WithConnection(MapCollections);
+ Execute.WithConnection(MigrateListMonitor);
+
+ Alter.Table("ImportLists").AlterColumn("Monitor").AsInt32().NotNullable();
+
+ Delete.Column("ShouldMonitor").FromTable("ImportLists");
+ Delete.FromTable("ImportLists").Row(new { Implementation = "TMDbCollectionImport" });
+ Delete.Column("Collection").FromTable("MovieMetadata");
+ }
+
+ private void MigrateCollections(IDbConnection conn, IDbTransaction tran)
+ {
+ var rootPaths = new List();
+ using (var getRootFolders = conn.CreateCommand())
+ {
+ getRootFolders.Transaction = tran;
+ getRootFolders.CommandText = @"SELECT ""Path"" FROM ""RootFolders""";
+
+ using (var definitionsReader = getRootFolders.ExecuteReader())
+ {
+ while (definitionsReader.Read())
+ {
+ string path = definitionsReader.GetString(0);
+ rootPaths.Add(path);
+ }
+ }
+ }
+
+ var newCollections = new List();
+ using (var cmd = conn.CreateCommand())
+ {
+ cmd.Transaction = tran;
+ cmd.CommandText = "SELECT \"Collection\", \"ProfileId\", \"MinimumAvailability\", \"Path\" FROM \"Movies\" JOIN \"MovieMetadata\" ON \"Movies\".\"MovieMetadataId\" = \"MovieMetadata\".\"Id\" WHERE \"Collection\" IS NOT NULL";
+
+ var addedCollections = new List();
+ var added = DateTime.UtcNow;
+
+ using (var reader = cmd.ExecuteReader())
+ {
+ while (reader.Read())
+ {
+ var collection = reader.GetString(0);
+ var qualityProfileId = reader.GetInt32(1);
+ var minimumAvailability = reader.GetInt32(2);
+ var moviePath = reader.GetString(3);
+ var data = STJson.Deserialize(collection);
+
+ if (newCollections.Any(d => d.TmdbId == data.TmdbId))
+ {
+ continue;
+ }
+
+ var rootFolderPath = rootPaths.Where(r => r.IsParentPath(moviePath))
+ .OrderByDescending(r => r.Length)
+ .FirstOrDefault();
+
+ if (rootFolderPath == null)
+ {
+ rootFolderPath = rootPaths.FirstOrDefault();
+ }
+
+ if (rootFolderPath == null)
+ {
+ rootFolderPath = moviePath.GetParentPath();
+ }
+
+ newCollections.Add(new MovieCollection208
+ {
+ TmdbId = data.TmdbId,
+ Title = data.Name,
+ CleanTitle = data.Name.CleanMovieTitle(),
+ SortTitle = Parser.Parser.NormalizeTitle(data.Name),
+ Added = added,
+ QualityProfileId = qualityProfileId,
+ RootFolderPath = rootFolderPath,
+ SearchOnAdd = true,
+ MinimumAvailability = minimumAvailability
+ });
+ }
+ }
+ }
+
+ var updateSql = "INSERT INTO \"Collections\" (\"TmdbId\", \"Title\", \"CleanTitle\", \"SortTitle\", \"Added\", \"QualityProfileId\", \"RootFolderPath\", \"SearchOnAdd\", \"MinimumAvailability\") VALUES (@TmdbId, @Title, @CleanTitle, @SortTitle, @Added, @QualityProfileId, @RootFolderPath, @SearchOnAdd, @MinimumAvailability)";
+ conn.Execute(updateSql, newCollections, transaction: tran);
+ }
+
+ private void MigrateCollectionMonitorStatus(IDbConnection conn, IDbTransaction tran)
+ {
+ var updatedCollections = new List();
+ using (var cmd = conn.CreateCommand())
+ {
+ cmd.Transaction = tran;
+ cmd.CommandText = "SELECT \"Enabled\", \"EnableAuto\", \"Settings\", \"ShouldMonitor\", \"Id\" FROM \"ImportLists\" WHERE \"Implementation\" = 'TMDbCollectionImport'";
+
+ using (var reader = cmd.ExecuteReader())
+ {
+ while (reader.Read())
+ {
+ var enabled = reader.GetBoolean(0);
+ var enabledAutoAdd = reader.GetBoolean(1);
+ var settings = reader.GetString(2);
+ var shouldMonitor = reader.GetBoolean(3);
+ var listId = reader.GetInt32(4);
+ var data = STJson.Deserialize(settings);
+
+ if (!enabled || !enabledAutoAdd || !int.TryParse(data.CollectionId, out var collectionId))
+ {
+ continue;
+ }
+
+ updatedCollections.Add(new MovieCollection208
+ {
+ TmdbId = collectionId,
+ Monitored = true
+ });
+ }
+ }
+ }
+
+ var updateSql = "UPDATE \"Collections\" SET \"Monitored\" = @Monitored WHERE \"TmdbId\" = @TmdbId";
+ conn.Execute(updateSql, updatedCollections, transaction: tran);
+ }
+
+ private void MigrateListMonitor(IDbConnection conn, IDbTransaction tran)
+ {
+ var updatedLists = new List();
+ using (var cmd = conn.CreateCommand())
+ {
+ cmd.Transaction = tran;
+ cmd.CommandText = "SELECT \"ShouldMonitor\", \"Id\" FROM \"ImportLists\"";
+
+ using (var reader = cmd.ExecuteReader())
+ {
+ while (reader.Read())
+ {
+ var shouldMonitor = reader.GetBoolean(0);
+ var listId = reader.GetInt32(1);
+
+ updatedLists.Add(new ImportList208
+ {
+ Monitor = shouldMonitor ? 0 : 2,
+ Id = listId
+ });
+ }
+ }
+ }
+
+ var updateSql = "UPDATE \"ImportLists\" SET \"Monitor\" = @Monitor WHERE \"Id\" = @Id";
+ conn.Execute(updateSql, updatedLists, transaction: tran);
+ }
+
+ private void MapCollections(IDbConnection conn, IDbTransaction tran)
+ {
+ var updatedMeta = new List();
+
+ using (var cmd = conn.CreateCommand())
+ {
+ cmd.Transaction = tran;
+ cmd.CommandText = "SELECT \"Id\", \"Collection\" FROM \"MovieMetadata\" WHERE \"Collection\" IS NOT NULL";
+
+ using (var reader = cmd.ExecuteReader())
+ {
+ while (reader.Read())
+ {
+ var id = reader.GetInt32(0);
+ var collection = reader.GetString(1);
+ var data = STJson.Deserialize(collection);
+
+ var collectionId = data.TmdbId;
+ var collectionTitle = data.Name;
+
+ updatedMeta.Add(new MovieMetadata208
+ {
+ CollectionTitle = collectionTitle,
+ CollectionTmdbId = collectionId,
+ Id = id
+ });
+ }
+ }
+ }
+
+ var updateSql = "UPDATE \"MovieMetadata\" SET \"CollectionTmdbId\" = @CollectionTmdbId, \"CollectionTitle\" = @CollectionTitle WHERE \"Id\" = @Id";
+ conn.Execute(updateSql, updatedMeta, transaction: tran);
+ }
+
+ private class MovieCollection207
+ {
+ public string Name { get; set; }
+ public int TmdbId { get; set; }
+ }
+
+ private class MovieCollection208
+ {
+ public int Id { get; set; }
+ public string Title { get; set; }
+ public string CleanTitle { get; set; }
+ public string SortTitle { get; set; }
+ public DateTime Added { get; set; }
+ public int QualityProfileId { get; set; }
+ public string RootFolderPath { get; set; }
+ public bool SearchOnAdd { get; set; }
+ public int MinimumAvailability { get; set; }
+ public bool Monitored { get; set; }
+ public int TmdbId { get; set; }
+ }
+
+ private class MovieMetadata208
+ {
+ public int Id { get; set; }
+ public int CollectionTmdbId { get; set; }
+ public string CollectionTitle { get; set; }
+ }
+
+ private class ImportList208
+ {
+ public int Id { get; set; }
+ public int Monitor { get; set; }
+ }
+
+ private class TmdbCollectionSettings206
+ {
+ public string CollectionId { get; set; }
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Datastore/TableMapping.cs b/src/NzbDrone.Core/Datastore/TableMapping.cs
index cc609e986..357ce19c5 100644
--- a/src/NzbDrone.Core/Datastore/TableMapping.cs
+++ b/src/NzbDrone.Core/Datastore/TableMapping.cs
@@ -28,6 +28,7 @@ using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Movies.AlternativeTitles;
+using NzbDrone.Core.Movies.Collections;
using NzbDrone.Core.Movies.Credits;
using NzbDrone.Core.Movies.Translations;
using NzbDrone.Core.Notifications;
@@ -168,6 +169,8 @@ namespace NzbDrone.Core.Datastore
Mapper.Entity("MovieMetadata").RegisterModel()
.Ignore(s => s.Translations);
+
+ Mapper.Entity("Collections").RegisterModel();
}
private static void RegisterMappers()
diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeLabel.cs b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeLabel.cs
index a5da831ab..3d95413c5 100644
--- a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeLabel.cs
+++ b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeLabel.cs
@@ -1,8 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Newtonsoft.Json;
namespace NzbDrone.Core.Download.Clients.Deluge
diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStation2Task.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStation2Task.cs
index f7d9ab927..71e2ac11a 100644
--- a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStation2Task.cs
+++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStation2Task.cs
@@ -1,7 +1,3 @@
-using System.Collections.Generic;
-using Newtonsoft.Json;
-using NzbDrone.Common.Serializer;
-
namespace NzbDrone.Core.Download.Clients.DownloadStation
{
public class DownloadStation2Task
diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxySelector.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxySelector.cs
index 3991e357b..1eae7930e 100644
--- a/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxySelector.cs
+++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/Proxies/DownloadStationTaskProxySelector.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using NLog;
using NzbDrone.Common.Cache;
-using NzbDrone.Common.Http;
namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
{
diff --git a/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs b/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs
index 3ae3fa7b1..33fe7a052 100644
--- a/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs
+++ b/src/NzbDrone.Core/Download/Clients/Flood/Flood.cs
@@ -52,7 +52,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
switch (additionalTag)
{
case (int)AdditionalTags.Collection:
- result.Add(remoteMovie.Movie.MovieMetadata.Value.Collection.Name);
+ result.Add(remoteMovie.Movie.MovieMetadata.Value.CollectionTitle);
break;
case (int)AdditionalTags.Quality:
result.Add(remoteMovie.ParsedMovieInfo.Quality.Quality.ToString());
diff --git a/src/NzbDrone.Core/Download/DownloadClientBase.cs b/src/NzbDrone.Core/Download/DownloadClientBase.cs
index 76e729592..4819aef33 100644
--- a/src/NzbDrone.Core/Download/DownloadClientBase.cs
+++ b/src/NzbDrone.Core/Download/DownloadClientBase.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using FluentValidation.Results;
using NLog;
using NzbDrone.Common.Disk;
diff --git a/src/NzbDrone.Core/Download/Extensions/XmlExtensions.cs b/src/NzbDrone.Core/Download/Extensions/XmlExtensions.cs
index 1e9deec9f..bce66c8bc 100644
--- a/src/NzbDrone.Core/Download/Extensions/XmlExtensions.cs
+++ b/src/NzbDrone.Core/Download/Extensions/XmlExtensions.cs
@@ -1,4 +1,3 @@
-using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;
diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs
index 6f427e232..e64f5b02d 100644
--- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs
+++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs
@@ -251,11 +251,11 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
details.Add(new XElement("country"));
- if (movie.MovieMetadata.Value.Collection?.Name != null)
+ if (movie.MovieMetadata.Value.CollectionTitle != null)
{
var setElement = new XElement("set");
- setElement.Add(new XElement("name", movie.MovieMetadata.Value.Collection.Name));
+ setElement.Add(new XElement("name", movie.MovieMetadata.Value.CollectionTitle));
setElement.Add(new XElement("overview"));
details.Add(setElement);
diff --git a/src/NzbDrone.Core/Extras/Metadata/MetadataFactory.cs b/src/NzbDrone.Core/Extras/Metadata/MetadataFactory.cs
index fad65a348..dc07e4d4f 100644
--- a/src/NzbDrone.Core/Extras/Metadata/MetadataFactory.cs
+++ b/src/NzbDrone.Core/Extras/Metadata/MetadataFactory.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
-using NzbDrone.Common.Composition;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.ThingiProvider;
diff --git a/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs
index 2bc24a5a8..3b41b929b 100644
--- a/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs
+++ b/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs
@@ -1,6 +1,5 @@
using System.Linq;
using NzbDrone.Common.Disk;
-using NzbDrone.Common.Extensions;
using NzbDrone.Core.Localization;
using NzbDrone.Core.Movies;
diff --git a/src/NzbDrone.Core/HealthCheck/Checks/MovieCollectionRootFolderCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/MovieCollectionRootFolderCheck.cs
new file mode 100644
index 000000000..60f749488
--- /dev/null
+++ b/src/NzbDrone.Core/HealthCheck/Checks/MovieCollectionRootFolderCheck.cs
@@ -0,0 +1,66 @@
+using System.Collections.Generic;
+using System.Linq;
+using NzbDrone.Common.Disk;
+using NzbDrone.Common.Extensions;
+using NzbDrone.Core.Localization;
+using NzbDrone.Core.Movies.Collections;
+using NzbDrone.Core.Movies.Events;
+
+namespace NzbDrone.Core.HealthCheck.Checks
+{
+ [CheckOn(typeof(CollectionEditedEvent), CheckOnCondition.Always)]
+ public class MovieCollectionRootFolderCheck : HealthCheckBase
+ {
+ private readonly IMovieCollectionService _collectionService;
+ private readonly IDiskProvider _diskProvider;
+
+ public MovieCollectionRootFolderCheck(IMovieCollectionService collectionService, IDiskProvider diskProvider, ILocalizationService localizationService)
+ : base(localizationService)
+ {
+ _collectionService = collectionService;
+ _diskProvider = diskProvider;
+ }
+
+ public override HealthCheck Check()
+ {
+ var collections = _collectionService.GetAllCollections();
+ var missingRootFolders = new Dictionary>();
+
+ foreach (var collection in collections)
+ {
+ var rootFolderPath = collection.RootFolderPath;
+
+ if (missingRootFolders.ContainsKey(rootFolderPath))
+ {
+ missingRootFolders[rootFolderPath].Add(collection);
+
+ continue;
+ }
+
+ if (rootFolderPath.IsNullOrWhiteSpace() || !_diskProvider.FolderExists(rootFolderPath))
+ {
+ missingRootFolders.Add(rootFolderPath, new List { collection });
+ }
+ }
+
+ if (missingRootFolders.Any())
+ {
+ if (missingRootFolders.Count == 1)
+ {
+ var missingRootFolder = missingRootFolders.First();
+ return new HealthCheck(GetType(), HealthCheckResult.Error, string.Format(_localizationService.GetLocalizedString("MovieCollectionMissingRoot"), FormatRootFolder(missingRootFolder.Key, missingRootFolder.Value)), "#movie-collection-missing-root-folder");
+ }
+
+ var message = string.Format(_localizationService.GetLocalizedString("MovieCollectionMultipleMissingRoots"), string.Join(" | ", missingRootFolders.Select(m => FormatRootFolder(m.Key, m.Value))));
+ return new HealthCheck(GetType(), HealthCheckResult.Error, message, "#movie-collection-missing-root-folder");
+ }
+
+ return new HealthCheck(GetType());
+ }
+
+ private string FormatRootFolder(string rootFolderPath, List collections)
+ {
+ return $"{rootFolderPath} ({string.Join(", ", collections.Select(l => l.Title))})";
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/HealthCheck/Checks/PackageGlobalMessageCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/PackageGlobalMessageCheck.cs
index 98d40734b..9299088aa 100644
--- a/src/NzbDrone.Core/HealthCheck/Checks/PackageGlobalMessageCheck.cs
+++ b/src/NzbDrone.Core/HealthCheck/Checks/PackageGlobalMessageCheck.cs
@@ -1,7 +1,3 @@
-using System;
-using System.Linq;
-using System.Text.RegularExpressions;
-using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Localization;
diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedCollections.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedCollections.cs
new file mode 100644
index 000000000..233a8d9db
--- /dev/null
+++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedCollections.cs
@@ -0,0 +1,28 @@
+using Dapper;
+using NzbDrone.Core.Datastore;
+
+namespace NzbDrone.Core.Housekeeping.Housekeepers
+{
+ public class CleanupOrphanedCollections : IHousekeepingTask
+ {
+ private readonly IMainDatabase _database;
+
+ public CleanupOrphanedCollections(IMainDatabase database)
+ {
+ _database = database;
+ }
+
+ public void Clean()
+ {
+ using (var mapper = _database.OpenConnection())
+ {
+ mapper.Execute(@"DELETE FROM ""Collections""
+ WHERE ""TmdbId"" IN (
+ SELECT ""Collections"".""TmdbId"" FROM ""Collections""
+ LEFT OUTER JOIN ""MovieMetadata""
+ ON ""Collections"".""TmdbId"" = ""MovieMetadata"".""CollectionTmdbId""
+ WHERE ""MovieMetadata"".""Id"" IS NULL)");
+ }
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedMovieMetadata.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedMovieMetadata.cs
index e7e10bc40..aad19ad07 100644
--- a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedMovieMetadata.cs
+++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupOrphanedMovieMetadata.cs
@@ -20,8 +20,9 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
WHERE ""Id"" IN (
SELECT ""MovieMetadata"".""Id"" FROM ""MovieMetadata""
LEFT OUTER JOIN ""Movies"" ON ""Movies"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
+ LEFT OUTER JOIN ""Collections"" ON ""Collections"".""TmdbId"" = ""MovieMetadata"".""CollectionTmdbId""
LEFT OUTER JOIN ""ImportListMovies"" ON ""ImportListMovies"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
- WHERE ""Movies"".""Id"" IS NULL AND ""ImportListMovies"".""Id"" IS NULL)");
+ WHERE ""Movies"".""Id"" IS NULL AND ""ImportListMovies"".""Id"" IS NULL AND ""Collections"".""Id"" IS NULL)");
}
}
}
diff --git a/src/NzbDrone.Core/ImportLists/FetchAndParseImportListService.cs b/src/NzbDrone.Core/ImportLists/FetchAndParseImportListService.cs
index 3f0d24175..a2ac8b020 100644
--- a/src/NzbDrone.Core/ImportLists/FetchAndParseImportListService.cs
+++ b/src/NzbDrone.Core/ImportLists/FetchAndParseImportListService.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NLog;
-using NzbDrone.Common.Extensions;
using NzbDrone.Common.Instrumentation.Extensions;
using NzbDrone.Common.TPL;
using NzbDrone.Core.ImportLists.ImportListMovies;
diff --git a/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs b/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs
index 97fadae36..0a8c0eeef 100644
--- a/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs
+++ b/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs
@@ -13,7 +13,7 @@ namespace NzbDrone.Core.ImportLists
public bool Enabled { get; set; }
public bool EnableAuto { get; set; }
- public bool ShouldMonitor { get; set; }
+ public MonitorTypes Monitor { get; set; }
public MovieStatusType MinimumAvailability { get; set; }
public int ProfileId { get; set; }
public string RootFolderPath { get; set; }
diff --git a/src/NzbDrone.Core/ImportLists/ImportListFactory.cs b/src/NzbDrone.Core/ImportLists/ImportListFactory.cs
index 14b17bb4f..409680b8a 100644
--- a/src/NzbDrone.Core/ImportLists/ImportListFactory.cs
+++ b/src/NzbDrone.Core/ImportLists/ImportListFactory.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
-using NzbDrone.Common.Composition;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.ThingiProvider;
diff --git a/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs b/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs
index 7fb5a01ee..204db5b89 100644
--- a/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs
+++ b/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs
@@ -91,11 +91,11 @@ namespace NzbDrone.Core.ImportLists
// Append Artist if not already in DB or already on add list
if (moviesToAdd.All(s => s.TmdbId != report.TmdbId))
{
- var monitored = importList.ShouldMonitor;
+ var monitorType = importList.Monitor;
moviesToAdd.Add(new Movie
{
- Monitored = monitored,
+ Monitored = monitorType != MonitorTypes.None,
RootFolderPath = importList.RootFolderPath,
ProfileId = importList.ProfileId,
MinimumAvailability = importList.MinimumAvailability,
@@ -106,7 +106,8 @@ namespace NzbDrone.Core.ImportLists
ImdbId = report.ImdbId,
AddOptions = new AddMovieOptions
{
- SearchForMovie = monitored && importList.SearchOnAdd,
+ SearchForMovie = monitorType != MonitorTypes.None && importList.SearchOnAdd,
+ Monitor = monitorType
}
});
}
diff --git a/src/NzbDrone.Core/ImportLists/TMDb/Collection/TMDbCollectionImport.cs b/src/NzbDrone.Core/ImportLists/TMDb/Collection/TMDbCollectionImport.cs
deleted file mode 100644
index a7f691c13..000000000
--- a/src/NzbDrone.Core/ImportLists/TMDb/Collection/TMDbCollectionImport.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using NLog;
-using NzbDrone.Common.Cloud;
-using NzbDrone.Common.Http;
-using NzbDrone.Core.Configuration;
-using NzbDrone.Core.MetadataSource;
-using NzbDrone.Core.Parser;
-
-namespace NzbDrone.Core.ImportLists.TMDb.Collection
-{
- public class TMDbCollectionImport : TMDbImportListBase
- {
- public TMDbCollectionImport(IRadarrCloudRequestBuilder requestBuilder,
- IHttpClient httpClient,
- IImportListStatusService importListStatusService,
- IConfigService configService,
- IParsingService parsingService,
- ISearchForNewMovie searchForNewMovie,
- Logger logger)
- : base(requestBuilder, httpClient, importListStatusService, configService, parsingService, searchForNewMovie, logger)
- {
- }
-
- public override string Name => "TMDb Collection";
- public override bool Enabled => true;
- public override bool EnableAuto => false;
-
- public override IParseImportListResponse GetParser()
- {
- return new TMDbCollectionParser();
- }
-
- public override IImportListRequestGenerator GetRequestGenerator()
- {
- return new TMDbCollectionRequestGenerator()
- {
- RequestBuilder = _requestBuilder,
- Settings = Settings,
- Logger = _logger,
- HttpClient = _httpClient
- };
- }
- }
-}
diff --git a/src/NzbDrone.Core/ImportLists/TMDb/Collection/TMDbCollectionParser.cs b/src/NzbDrone.Core/ImportLists/TMDb/Collection/TMDbCollectionParser.cs
deleted file mode 100644
index b97f29e7c..000000000
--- a/src/NzbDrone.Core/ImportLists/TMDb/Collection/TMDbCollectionParser.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System.Collections.Generic;
-using Newtonsoft.Json;
-using NzbDrone.Common.Extensions;
-using NzbDrone.Core.ImportLists.ImportListMovies;
-
-namespace NzbDrone.Core.ImportLists.TMDb.Collection
-{
- public class TMDbCollectionParser : TMDbParser
- {
- public override IList ParseResponse(ImportListResponse importResponse)
- {
- var movies = new List();
-
- if (!PreProcess(importResponse))
- {
- return movies;
- }
-
- var jsonResponse = JsonConvert.DeserializeObject(importResponse.Content);
-
- // no movies were return
- if (jsonResponse == null)
- {
- return movies;
- }
-
- foreach (var movie in jsonResponse.Parts)
- {
- // Movies with no Year Fix
- if (string.IsNullOrWhiteSpace(movie.ReleaseDate))
- {
- continue;
- }
-
- movies.AddIfNotNull(MapListMovie(movie));
- }
-
- return movies;
- }
- }
-}
diff --git a/src/NzbDrone.Core/ImportLists/TMDb/Collection/TMDbCollectionRequestGenerator.cs b/src/NzbDrone.Core/ImportLists/TMDb/Collection/TMDbCollectionRequestGenerator.cs
deleted file mode 100644
index 10ac3342a..000000000
--- a/src/NzbDrone.Core/ImportLists/TMDb/Collection/TMDbCollectionRequestGenerator.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using System.Collections.Generic;
-using NLog;
-using NzbDrone.Common.Http;
-
-namespace NzbDrone.Core.ImportLists.TMDb.Collection
-{
- public class TMDbCollectionRequestGenerator : IImportListRequestGenerator
- {
- public TMDbCollectionSettings Settings { get; set; }
- public IHttpClient HttpClient { get; set; }
- public IHttpRequestBuilderFactory RequestBuilder { get; set; }
- public Logger Logger { get; set; }
-
- public TMDbCollectionRequestGenerator()
- {
- }
-
- public virtual ImportListPageableRequestChain GetMovies()
- {
- var pageableRequests = new ImportListPageableRequestChain();
-
- pageableRequests.Add(GetMoviesRequest());
-
- return pageableRequests;
- }
-
- private IEnumerable GetMoviesRequest()
- {
- Logger.Info($"Importing TMDb movies from collection: {Settings.CollectionId}");
-
- yield return new ImportListRequest(RequestBuilder.Create()
- .SetSegment("api", "3")
- .SetSegment("route", "collection")
- .SetSegment("id", Settings.CollectionId)
- .SetSegment("secondaryRoute", "")
- .Build());
- }
- }
-}
diff --git a/src/NzbDrone.Core/ImportLists/TMDb/Collection/TMDbCollectionSettings.cs b/src/NzbDrone.Core/ImportLists/TMDb/Collection/TMDbCollectionSettings.cs
deleted file mode 100644
index 59200a39f..000000000
--- a/src/NzbDrone.Core/ImportLists/TMDb/Collection/TMDbCollectionSettings.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Text.RegularExpressions;
-using FluentValidation;
-using NzbDrone.Core.Annotations;
-
-namespace NzbDrone.Core.ImportLists.TMDb.Collection
-{
- public class TMDbCollectionSettingsValidator : TMDbSettingsBaseValidator
- {
- public TMDbCollectionSettingsValidator()
- : base()
- {
- RuleFor(c => c.CollectionId).Matches(@"^[1-9][0-9]*$", RegexOptions.IgnoreCase);
- }
- }
-
- public class TMDbCollectionSettings : TMDbSettingsBase
- {
- protected override AbstractValidator Validator => new TMDbCollectionSettingsValidator();
-
- public TMDbCollectionSettings()
- {
- CollectionId = "";
- }
-
- [FieldDefinition(1, Label = "Collection Id", Type = FieldType.Textbox, HelpText = "TMDb Id of Collection to Follow")]
- public string CollectionId { get; set; }
- }
-}
diff --git a/src/NzbDrone.Core/ImportLists/Trakt/List/TraktListRequestGenerator.cs b/src/NzbDrone.Core/ImportLists/Trakt/List/TraktListRequestGenerator.cs
index 591c852a3..78b4b6885 100644
--- a/src/NzbDrone.Core/ImportLists/Trakt/List/TraktListRequestGenerator.cs
+++ b/src/NzbDrone.Core/ImportLists/Trakt/List/TraktListRequestGenerator.cs
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Net.Http;
-using NzbDrone.Common.Http;
using NzbDrone.Core.Notifications.Trakt;
namespace NzbDrone.Core.ImportLists.Trakt.List
diff --git a/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularRequestGenerator.cs b/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularRequestGenerator.cs
index 59004deee..82f1cf613 100644
--- a/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularRequestGenerator.cs
+++ b/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularRequestGenerator.cs
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Net.Http;
-using NzbDrone.Common.Http;
using NzbDrone.Core.Notifications.Trakt;
namespace NzbDrone.Core.ImportLists.Trakt.Popular
diff --git a/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserRequestGenerator.cs b/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserRequestGenerator.cs
index bc058e34b..24017d23f 100644
--- a/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserRequestGenerator.cs
+++ b/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserRequestGenerator.cs
@@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.Net.Http;
using NzbDrone.Common.Extensions;
-using NzbDrone.Common.Http;
using NzbDrone.Core.Notifications.Trakt;
namespace NzbDrone.Core.ImportLists.Trakt.User
diff --git a/src/NzbDrone.Core/Indexers/IndexerBase.cs b/src/NzbDrone.Core/Indexers/IndexerBase.cs
index 11b489245..d71f6fc87 100644
--- a/src/NzbDrone.Core/Indexers/IndexerBase.cs
+++ b/src/NzbDrone.Core/Indexers/IndexerBase.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using FluentValidation.Results;
using NLog;
-using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser;
diff --git a/src/NzbDrone.Core/Indexers/IndexerFactory.cs b/src/NzbDrone.Core/Indexers/IndexerFactory.cs
index 08b260609..4e72a36cd 100644
--- a/src/NzbDrone.Core/Indexers/IndexerFactory.cs
+++ b/src/NzbDrone.Core/Indexers/IndexerFactory.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using FluentValidation.Results;
using NLog;
-using NzbDrone.Common.Composition;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.ThingiProvider;
diff --git a/src/NzbDrone.Core/Indexers/Newznab/NewznabRssParser.cs b/src/NzbDrone.Core/Indexers/Newznab/NewznabRssParser.cs
index 1111a1c41..6a54424e9 100644
--- a/src/NzbDrone.Core/Indexers/Newznab/NewznabRssParser.cs
+++ b/src/NzbDrone.Core/Indexers/Newznab/NewznabRssParser.cs
@@ -4,7 +4,6 @@ using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using NzbDrone.Common.Extensions;
-using NzbDrone.Common.Http;
using NzbDrone.Core.Indexers.Exceptions;
using NzbDrone.Core.Parser.Model;
diff --git a/src/NzbDrone.Core/Jobs/TaskManager.cs b/src/NzbDrone.Core/Jobs/TaskManager.cs
index 28e83817e..fab9e4b0b 100644
--- a/src/NzbDrone.Core/Jobs/TaskManager.cs
+++ b/src/NzbDrone.Core/Jobs/TaskManager.cs
@@ -101,6 +101,12 @@ namespace NzbDrone.Core.Jobs
TypeName = typeof(CleanUpRecycleBinCommand).FullName
},
+ new ScheduledTask
+ {
+ Interval = 24 * 60,
+ TypeName = typeof(RefreshCollectionsCommand).FullName
+ },
+
new ScheduledTask
{
Interval = GetBackupInterval(),
diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json
index fa7aa182b..bde6e042e 100644
--- a/src/NzbDrone.Core/Localization/Core/en.json
+++ b/src/NzbDrone.Core/Localization/Core/en.json
@@ -17,7 +17,6 @@
"AddListExclusion": "Add List Exclusion",
"AddMovie": "Add Movie",
"AddMovies": "Add Movies",
- "AddMoviesMonitored": "Add Movies Monitored",
"AddNew": "Add New",
"AddNewMessage": "It's easy to add a new movie, just start typing the name of the movie you want to add",
"AddNewMovie": "Add New Movie",
@@ -33,6 +32,7 @@
"Agenda": "Agenda",
"AgeWhenGrabbed": "Age (when grabbed)",
"All": "All",
+ "AllCollectionsHiddenDueToFilter": "All collections are hidden due to applied filter.",
"AllFiles": "All Files",
"AllMoviesHiddenDueToFilter": "All movies are hidden due to applied filter.",
"AllMoviesInPathHaveBeenImported": "All movies in {0} have been imported",
@@ -137,6 +137,8 @@
"Close": "Close",
"CloseCurrentModal": "Close Current Modal",
"Collection": "Collection",
+ "Collections": "Collections",
+ "CollectionsSelectedInterp": "{0} Collections(s) Selected",
"ColonReplacement": "Colon Replacement",
"ColonReplacementFormatHelpText": "Change how Radarr handles colon replacement",
"Columns": "Columns",
@@ -266,6 +268,7 @@
"DownloadWarningCheckDownloadClientForMoreDetails": "Download warning: check download client for more details",
"Duration": "Duration",
"Edit": "Edit",
+ "EditCollection": "Edit Collection",
"EditCustomFormat": "Edit Custom Format",
"EditDelayProfile": "Edit Delay Profile",
"EditGroups": "Edit Groups",
@@ -537,11 +540,14 @@
"Mode": "Mode",
"Monday": "Monday",
"Monitor": "Monitor",
+ "MonitorCollection": "Monitor Collection",
"Monitored": "Monitored",
+ "MonitoredCollectionHelpText": "Monitor to automatically have movies from this collection added to the library",
"MonitoredHelpText": "Download movie if available",
"MonitoredOnly": "Monitored Only",
"MonitoredStatus": "Monitored/Status",
"MonitorMovie": "Monitor Movie",
+ "MonitorMovies": "Monitor Movies",
"Month": "Month",
"Months": "Months",
"More": "More",
@@ -554,7 +560,10 @@
"MoveFolders2": "Would you like to move the movie files from '{0}' to '{1}' ?",
"Movie": "Movie",
"MovieAlreadyExcluded": "Movie already Excluded",
+ "MovieAndCollection": "Movie and Collection",
"MovieChat": "Movie Chat",
+ "MovieCollectionMissingRoot": "Missing root folder for movie collection: {0}",
+ "MovieCollectionMultipleMissingRoots": "Multiple root folders are missing for movie collections: {0}",
"MovieDetailsNextMovie": "Movie Details: Next Movie",
"MovieDetailsPreviousMovie": "Movie Details: Previous Movie",
"MovieEditor": "Movie Editor",
@@ -577,6 +586,7 @@
"MovieIsRecommend": "Movie is recommended based on recent addition",
"MovieIsUnmonitored": "Movie is unmonitored",
"MovieNaming": "Movie Naming",
+ "MovieOnly": "Movie Only",
"Movies": "Movies",
"MoviesSelectedInterp": "{0} Movie(s) Selected",
"MovieTitle": "Movie Title",
@@ -595,11 +605,11 @@
"Never": "Never",
"New": "New",
"NextExecution": "Next Execution",
- "No": "No",
"NoAltTitle": "No alternative titles.",
"NoBackupsAreAvailable": "No backups are available",
"NoChange": "No Change",
"NoChanges": "No Changes",
+ "NoCollections": "No collections found, to get started you'll want to add a new movie, or import some existing ones",
"NoEventsFound": "No events found",
"NoHistory": "No history",
"NoLeaveIt": "No, Leave It",
@@ -749,6 +759,7 @@
"Redownload": "Redownload",
"Refresh": "Refresh",
"RefreshAndScan": "Refresh & Scan",
+ "RefreshCollections": "Refresh Collections",
"RefreshInformationAndScanDisk": "Refresh information and scan disk",
"RefreshLists": "Refresh Lists",
"RefreshMonitoredIntervalHelpText": "How often to refresh monitored downloads from download clients, minimum 1 minute",
@@ -855,6 +866,7 @@
"Score": "Score",
"Script": "Script",
"ScriptPath": "Script Path",
+ "ScrollMovies": "Scroll Movies",
"Search": "Search",
"SearchAll": "Search All",
"SearchCutoffUnmet": "Search Cutoff Unmet",
@@ -865,7 +877,8 @@
"SearchMissing": "Search Missing",
"SearchMovie": "Search Movie",
"SearchOnAdd": "Search on Add",
- "SearchOnAddHelpText": "Search for movies on this list when added to Radarr",
+ "SearchOnAddCollectionHelpText": "Search for movies on this collection when added to library",
+ "SearchOnAddHelpText": "Search for movies on this list when added to library",
"SearchSelected": "Search Selected",
"Seconds": "Seconds",
"Security": "Security",
@@ -901,12 +914,13 @@
"SettingsTimeFormat": "Time Format",
"SettingsWeekColumnHeader": "Week Column Header",
"SettingsWeekColumnHeaderHelpText": "Shown above each column when week is the active view",
- "ShouldMonitorHelpText": "If enabled, movies added by this list are added and monitored",
+ "ShouldMonitorHelpText": "Should Movies or Collections added by this list be added as monitored",
"ShowAdvanced": "Show Advanced",
"ShowAsAllDayEvents": "Show as All-Day Events",
"ShowCertification": "Show Certification",
"ShowCinemaRelease": "Show Cinema Release Date",
"showCinemaReleaseHelpText": "Show cinema release date under poster",
+ "ShowCollectionDetails": "Show Collection Status",
"ShowCutoffUnmetIconHelpText": "Show icon for files when the cutoff hasn't been met",
"ShowDateAdded": "Show Date Added",
"ShowGenres": "Show Genres",
@@ -915,6 +929,7 @@
"ShowMovieInformation": "Show Movie Information",
"ShowMovieInformationHelpText": "Show movie genres and certification",
"ShownClickToHide": "Shown, click to hide",
+ "ShowOverview": "Show Overview",
"ShowPath": "Show Path",
"ShowQualityProfile": "Show Quality Profile",
"ShowQualityProfileHelpText": "Show quality profile under poster",
@@ -1029,6 +1044,7 @@
"UnableToLoadAltTitle": "Unable to load alternative titles.",
"UnableToLoadBackups": "Unable to load backups",
"UnableToLoadBlocklist": "Unable to load blocklist",
+ "UnableToLoadCollections": "Unable to load collections",
"UnableToLoadCustomFormats": "Unable to load Custom Formats",
"UnableToLoadDelayProfiles": "Unable to load Delay Profiles",
"UnableToLoadDownloadClientOptions": "Unable to load download client options",
@@ -1114,7 +1130,6 @@
"Wiki": "Wiki",
"WouldYouLikeToRestoreBackup": "Would you like to restore the backup {0} ?",
"Year": "Year",
- "Yes": "Yes",
"YesCancel": "Yes, Cancel",
"YesMoveFiles": "Yes, Move the Files",
"Yesterday": "Yesterday",
diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualitySpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualitySpecification.cs
index eceb8693a..0592f3b3e 100644
--- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualitySpecification.cs
+++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualitySpecification.cs
@@ -4,7 +4,6 @@ using NzbDrone.Common.Extensions;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.History;
-using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
diff --git a/src/NzbDrone.Core/MetadataSource/IProvideMovieInfo.cs b/src/NzbDrone.Core/MetadataSource/IProvideMovieInfo.cs
index 55c470b82..b2323f7b6 100644
--- a/src/NzbDrone.Core/MetadataSource/IProvideMovieInfo.cs
+++ b/src/NzbDrone.Core/MetadataSource/IProvideMovieInfo.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using NzbDrone.Core.Movies;
+using NzbDrone.Core.Movies.Collections;
using NzbDrone.Core.Movies.Credits;
namespace NzbDrone.Core.MetadataSource
@@ -9,6 +10,7 @@ namespace NzbDrone.Core.MetadataSource
{
MovieMetadata GetMovieByImdbId(string imdbId);
Tuple> GetMovieInfo(int tmdbId);
+ MovieCollection GetCollectionInfo(int tmdbId);
List GetBulkMovieInfo(List tmdbIds);
HashSet GetChangedMovies(DateTime startTime);
diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/CollectionResource.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/CollectionResource.cs
index fb4194200..65603bcac 100644
--- a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/CollectionResource.cs
+++ b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/CollectionResource.cs
@@ -5,7 +5,9 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
public class CollectionResource
{
public string Name { get; set; }
+ public string Overview { get; set; }
public int TmdbId { get; set; }
public List Images { get; set; }
+ public List Parts { get; set; }
}
}
diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs
index c1adda9b7..29d21c814 100644
--- a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs
+++ b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs
@@ -14,6 +14,7 @@ using NzbDrone.Core.MediaCover;
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Movies.AlternativeTitles;
+using NzbDrone.Core.Movies.Collections;
using NzbDrone.Core.Movies.Credits;
using NzbDrone.Core.Movies.Translations;
using NzbDrone.Core.Parser;
@@ -101,6 +102,35 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
return new Tuple>(movie, credits.ToList());
}
+ public MovieCollection GetCollectionInfo(int tmdbId)
+ {
+ var httpRequest = _radarrMetadata.Create()
+ .SetSegment("route", "movie/collection")
+ .Resource(tmdbId.ToString())
+ .Build();
+
+ httpRequest.AllowAutoRedirect = true;
+ httpRequest.SuppressHttpError = true;
+
+ var httpResponse = _httpClient.Get(httpRequest);
+
+ if (httpResponse.HasHttpError)
+ {
+ if (httpResponse.StatusCode == HttpStatusCode.NotFound)
+ {
+ throw new MovieNotFoundException(tmdbId);
+ }
+ else
+ {
+ throw new HttpException(httpRequest, httpResponse);
+ }
+ }
+
+ var collection = MapCollection(httpResponse.Resource);
+
+ return collection;
+ }
+
public List GetBulkMovieInfo(List tmdbIds)
{
var httpRequest = _radarrMetadata.Create()
@@ -257,7 +287,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
if (resource.Collection != null)
{
- movie.Collection = new MovieCollection { Name = resource.Collection.Name, TmdbId = resource.Collection.TmdbId };
+ movie.CollectionTmdbId = resource.Collection.TmdbId;
+ movie.CollectionTitle = resource.Collection.Name;
}
return movie;
@@ -470,6 +501,22 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
return movie;
}
+ private MovieCollection MapCollection(CollectionResource arg)
+ {
+ var collection = new MovieCollection
+ {
+ TmdbId = arg.TmdbId,
+ Title = arg.Name,
+ Overview = arg.Overview,
+ CleanTitle = arg.Name.CleanMovieTitle(),
+ SortTitle = Parser.Parser.NormalizeTitle(arg.Name),
+ Images = arg.Images?.Select(MapImage).ToList() ?? new List(),
+ Movies = arg.Parts?.Select(x => MapMovie(x)).ToList() ?? new List()
+ };
+
+ return collection;
+ }
+
private static Credit MapCast(CastResource arg)
{
var newActor = new Credit
diff --git a/src/NzbDrone.Core/Movies/AddMovieService.cs b/src/NzbDrone.Core/Movies/AddMovieService.cs
index b2a123532..71b94ea88 100644
--- a/src/NzbDrone.Core/Movies/AddMovieService.cs
+++ b/src/NzbDrone.Core/Movies/AddMovieService.cs
@@ -8,6 +8,7 @@ using NLog;
using NzbDrone.Common.EnsureThat;
using NzbDrone.Core.Exceptions;
using NzbDrone.Core.MetadataSource;
+using NzbDrone.Core.Movies.Collections;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Parser;
using NzbDrone.Core.RootFolders;
@@ -76,6 +77,7 @@ namespace NzbDrone.Core.Movies
movie = SetPropertiesAndValidate(movie);
movie.Added = added;
+
moviesToAdd.Add(movie);
}
catch (ValidationException ex)
diff --git a/src/NzbDrone.Core/Movies/AlternativeTitles/AlternativeTitleService.cs b/src/NzbDrone.Core/Movies/AlternativeTitles/AlternativeTitleService.cs
index e0fff47f5..58ae90d45 100644
--- a/src/NzbDrone.Core/Movies/AlternativeTitles/AlternativeTitleService.cs
+++ b/src/NzbDrone.Core/Movies/AlternativeTitles/AlternativeTitleService.cs
@@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using NLog;
-using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Movies.Events;
diff --git a/src/NzbDrone.Core/Movies/Collections/AddMovieCollectionService.cs b/src/NzbDrone.Core/Movies/Collections/AddMovieCollectionService.cs
new file mode 100644
index 000000000..4b4788bb8
--- /dev/null
+++ b/src/NzbDrone.Core/Movies/Collections/AddMovieCollectionService.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using FluentValidation;
+using FluentValidation.Results;
+using NLog;
+using NzbDrone.Common.EnsureThat;
+using NzbDrone.Core.Exceptions;
+using NzbDrone.Core.MetadataSource;
+using NzbDrone.Core.Parser;
+
+namespace NzbDrone.Core.Movies.Collections
+{
+ public interface IAddMovieCollectionService
+ {
+ MovieCollection AddMovieCollection(MovieCollection newCollection);
+ }
+
+ public class AddMovieCollectionService : IAddMovieCollectionService
+ {
+ private readonly IMovieCollectionService _collectionService;
+ private readonly IProvideMovieInfo _movieInfo;
+ private readonly Logger _logger;
+
+ public AddMovieCollectionService(IMovieCollectionService collectionService,
+ IProvideMovieInfo movieInfo,
+ Logger logger)
+ {
+ _collectionService = collectionService;
+ _movieInfo = movieInfo;
+ _logger = logger;
+ }
+
+ public MovieCollection AddMovieCollection(MovieCollection newCollection)
+ {
+ Ensure.That(newCollection, () => newCollection).IsNotNull();
+
+ var existingCollection = _collectionService.FindByTmdbId(newCollection.TmdbId);
+
+ if (existingCollection != null)
+ {
+ return existingCollection;
+ }
+
+ newCollection = AddSkyhookData(newCollection);
+ newCollection = SetPropertiesAndValidate(newCollection);
+
+ _logger.Info("Adding Collection {0}", newCollection);
+
+ _collectionService.AddCollection(newCollection);
+
+ return newCollection;
+ }
+
+ private MovieCollection AddSkyhookData(MovieCollection newCollection)
+ {
+ MovieCollection collection;
+
+ try
+ {
+ collection = _movieInfo.GetCollectionInfo(newCollection.TmdbId);
+ }
+ catch (MovieNotFoundException)
+ {
+ _logger.Error("TmdbId {0} was not found, it may have been removed from TMDb.", newCollection.TmdbId);
+
+ throw new ValidationException(new List
+ {
+ new ValidationFailure("TmdbId", $"A collection with this ID was not found.", newCollection.TmdbId)
+ });
+ }
+
+ collection.ApplyChanges(newCollection);
+
+ return collection;
+ }
+
+ private MovieCollection SetPropertiesAndValidate(MovieCollection newCollection)
+ {
+ newCollection.CleanTitle = newCollection.Title.CleanMovieTitle();
+ newCollection.SortTitle = MovieTitleNormalizer.Normalize(newCollection.Title, newCollection.TmdbId);
+ newCollection.Added = DateTime.UtcNow;
+
+ return newCollection;
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Movies/Collections/MovieCollection.cs b/src/NzbDrone.Core/Movies/Collections/MovieCollection.cs
new file mode 100644
index 000000000..18a33b28f
--- /dev/null
+++ b/src/NzbDrone.Core/Movies/Collections/MovieCollection.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using NzbDrone.Core.Datastore;
+
+namespace NzbDrone.Core.Movies.Collections
+{
+ public class MovieCollection : ModelBase
+ {
+ public MovieCollection()
+ {
+ Images = new List();
+ }
+
+ public string Title { get; set; }
+ public string CleanTitle { get; set; }
+ public string SortTitle { get; set; }
+ public int TmdbId { get; set; }
+ public string Overview { get; set; }
+ public bool Monitored { get; set; }
+ public int QualityProfileId { get; set; }
+ public string RootFolderPath { get; set; }
+ public bool SearchOnAdd { get; set; }
+ public MovieStatusType MinimumAvailability { get; set; }
+ public DateTime? LastInfoSync { get; set; }
+ public List Images { get; set; }
+ public DateTime Added { get; set; }
+ public List Movies { get; set; }
+
+ public void ApplyChanges(MovieCollection otherCollection)
+ {
+ TmdbId = otherCollection.TmdbId;
+
+ Monitored = otherCollection.Monitored;
+ SearchOnAdd = otherCollection.SearchOnAdd;
+ QualityProfileId = otherCollection.QualityProfileId;
+ MinimumAvailability = otherCollection.MinimumAvailability;
+ RootFolderPath = otherCollection.RootFolderPath;
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Movies/Collections/MovieCollectionAddedHandler.cs b/src/NzbDrone.Core/Movies/Collections/MovieCollectionAddedHandler.cs
new file mode 100644
index 000000000..bf448560d
--- /dev/null
+++ b/src/NzbDrone.Core/Movies/Collections/MovieCollectionAddedHandler.cs
@@ -0,0 +1,23 @@
+using System.Collections.Generic;
+using NzbDrone.Core.Messaging.Commands;
+using NzbDrone.Core.Messaging.Events;
+using NzbDrone.Core.Movies.Commands;
+using NzbDrone.Core.Movies.Events;
+
+namespace NzbDrone.Core.Movies
+{
+ public class MovieCollectionAddedHandler : IHandle
+ {
+ private readonly IManageCommandQueue _commandQueueManager;
+
+ public MovieCollectionAddedHandler(IManageCommandQueue commandQueueManager)
+ {
+ _commandQueueManager = commandQueueManager;
+ }
+
+ public void Handle(CollectionAddedEvent message)
+ {
+ _commandQueueManager.Push(new RefreshCollectionsCommand(new List { message.Collection.Id }));
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Movies/Collections/MovieCollectionRepository.cs b/src/NzbDrone.Core/Movies/Collections/MovieCollectionRepository.cs
new file mode 100644
index 000000000..2017147fc
--- /dev/null
+++ b/src/NzbDrone.Core/Movies/Collections/MovieCollectionRepository.cs
@@ -0,0 +1,68 @@
+using System.Collections.Generic;
+using System.Linq;
+using NzbDrone.Core.Datastore;
+using NzbDrone.Core.Messaging.Events;
+
+namespace NzbDrone.Core.Movies.Collections
+{
+ public interface IMovieCollectionRepository : IBasicRepository
+ {
+ public MovieCollection GetByTmdbId(int tmdbId);
+ bool UpsertMany(List data);
+ }
+
+ public class MovieCollectionRepository : BasicRepository, IMovieCollectionRepository
+ {
+ public MovieCollectionRepository(IMainDatabase database, IEventAggregator eventAggregator)
+ : base(database, eventAggregator)
+ {
+ }
+
+ public MovieCollection GetByTmdbId(int tmdbId)
+ {
+ return Query(x => x.TmdbId == tmdbId).FirstOrDefault();
+ }
+
+ public List GetByTmdbId(List tmdbIds)
+ {
+ return Query(x => Enumerable.Contains(tmdbIds, x.TmdbId));
+ }
+
+ public bool UpsertMany(List data)
+ {
+ var existingMetadata = GetByTmdbId(data.Select(x => x.TmdbId).ToList());
+ var updateCollectionList = new List();
+ var addCollectionList = new List();
+ int upToDateMetadataCount = 0;
+
+ foreach (var collection in data)
+ {
+ var existing = existingMetadata.SingleOrDefault(x => x.TmdbId == collection.TmdbId);
+ if (existing != null)
+ {
+ // populate Id in remote data
+ collection.Id = existing.Id;
+
+ // responses vary, so try adding remote to what we have
+ if (!collection.Equals(existing))
+ {
+ updateCollectionList.Add(collection);
+ }
+ else
+ {
+ upToDateMetadataCount++;
+ }
+ }
+ else
+ {
+ addCollectionList.Add(collection);
+ }
+ }
+
+ UpdateMany(updateCollectionList);
+ InsertMany(addCollectionList);
+
+ return updateCollectionList.Count > 0 || addCollectionList.Count > 0;
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Movies/Collections/MovieCollectionService.cs b/src/NzbDrone.Core/Movies/Collections/MovieCollectionService.cs
new file mode 100644
index 000000000..efcaab428
--- /dev/null
+++ b/src/NzbDrone.Core/Movies/Collections/MovieCollectionService.cs
@@ -0,0 +1,117 @@
+using System.Collections.Generic;
+using System.Linq;
+using NzbDrone.Core.Messaging.Events;
+using NzbDrone.Core.Movies.Events;
+
+namespace NzbDrone.Core.Movies.Collections
+{
+ public interface IMovieCollectionService
+ {
+ MovieCollection AddCollection(MovieCollection collection);
+ MovieCollection GetCollection(int id);
+ MovieCollection FindByTmdbId(int tmdbId);
+ IEnumerable GetCollections(IEnumerable ids);
+ List GetAllCollections();
+ MovieCollection UpdateCollection(MovieCollection collection);
+ void RemoveCollection(MovieCollection collection);
+ bool Upsert(MovieCollection collection);
+ bool UpsertMany(List collections);
+ }
+
+ public class MovieCollectionService : IMovieCollectionService, IHandleAsync
+ {
+ private readonly IMovieCollectionRepository _repo;
+ private readonly IMovieMetadataService _movieMetadataService;
+ private readonly IEventAggregator _eventAggregator;
+
+ public MovieCollectionService(IMovieCollectionRepository repo, IMovieMetadataService movieMetadataService, IEventAggregator eventAggregator)
+ {
+ _repo = repo;
+ _movieMetadataService = movieMetadataService;
+ _eventAggregator = eventAggregator;
+ }
+
+ public MovieCollection AddCollection(MovieCollection newCollection)
+ {
+ var existing = _repo.GetByTmdbId(newCollection.TmdbId);
+
+ if (existing == null)
+ {
+ var collection = _repo.Insert(newCollection);
+
+ _eventAggregator.PublishEvent(new CollectionAddedEvent(collection));
+
+ return collection;
+ }
+
+ return existing;
+ }
+
+ public MovieCollection GetCollection(int id)
+ {
+ return _repo.Get(id);
+ }
+
+ public IEnumerable GetCollections(IEnumerable ids)
+ {
+ return _repo.Get(ids);
+ }
+
+ public List GetAllCollections()
+ {
+ return _repo.All().ToList();
+ }
+
+ public MovieCollection UpdateCollection(MovieCollection collection)
+ {
+ var storedCollection = GetCollection(collection.Id);
+
+ var updatedCollection = _repo.Update(collection);
+
+ _eventAggregator.PublishEvent(new CollectionEditedEvent(updatedCollection, storedCollection));
+
+ return updatedCollection;
+ }
+
+ public void RemoveCollection(MovieCollection collection)
+ {
+ _repo.Delete(collection);
+
+ _eventAggregator.PublishEvent(new CollectionDeletedEvent(collection));
+ }
+
+ public bool Upsert(MovieCollection collection)
+ {
+ return _repo.UpsertMany(new List { collection });
+ }
+
+ public bool UpsertMany(List collections)
+ {
+ return _repo.UpsertMany(collections);
+ }
+
+ public void HandleAsync(MoviesDeletedEvent message)
+ {
+ var collections = message.Movies.Select(x => x.MovieMetadata.Value.CollectionTmdbId).Distinct();
+
+ foreach (var collectionTmdbId in collections)
+ {
+ if (collectionTmdbId == 0 || _movieMetadataService.GetMoviesByCollectionTmdbId(collectionTmdbId).Any())
+ {
+ continue;
+ }
+
+ var collection = FindByTmdbId(collectionTmdbId);
+
+ _eventAggregator.PublishEvent(new CollectionDeletedEvent(collection));
+
+ _repo.Delete(collectionTmdbId);
+ }
+ }
+
+ public MovieCollection FindByTmdbId(int tmdbId)
+ {
+ return _repo.GetByTmdbId(tmdbId);
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Movies/Commands/RefreshCollectionsCommand.cs b/src/NzbDrone.Core/Movies/Commands/RefreshCollectionsCommand.cs
new file mode 100644
index 000000000..e33e40277
--- /dev/null
+++ b/src/NzbDrone.Core/Movies/Commands/RefreshCollectionsCommand.cs
@@ -0,0 +1,25 @@
+using System.Collections.Generic;
+using System.Linq;
+using NzbDrone.Core.Messaging.Commands;
+
+namespace NzbDrone.Core.Movies.Commands
+{
+ public class RefreshCollectionsCommand : Command
+ {
+ public List CollectionIds { get; set; }
+
+ public RefreshCollectionsCommand()
+ {
+ CollectionIds = new List();
+ }
+
+ public RefreshCollectionsCommand(List collectionIds)
+ {
+ CollectionIds = collectionIds;
+ }
+
+ public override bool SendUpdatesToClient => true;
+
+ public override bool UpdateScheduledTask => !CollectionIds.Any();
+ }
+}
diff --git a/src/NzbDrone.Core/Movies/Credits/CreditService.cs b/src/NzbDrone.Core/Movies/Credits/CreditService.cs
index 724b560a5..cf6743612 100644
--- a/src/NzbDrone.Core/Movies/Credits/CreditService.cs
+++ b/src/NzbDrone.Core/Movies/Credits/CreditService.cs
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Linq;
-using NzbDrone.Common.Extensions;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Movies.Events;
diff --git a/src/NzbDrone.Core/Movies/Events/CollectionAddedEvent.cs b/src/NzbDrone.Core/Movies/Events/CollectionAddedEvent.cs
new file mode 100644
index 000000000..19e1351ff
--- /dev/null
+++ b/src/NzbDrone.Core/Movies/Events/CollectionAddedEvent.cs
@@ -0,0 +1,15 @@
+using NzbDrone.Common.Messaging;
+using NzbDrone.Core.Movies.Collections;
+
+namespace NzbDrone.Core.Movies.Events
+{
+ public class CollectionAddedEvent : IEvent
+ {
+ public MovieCollection Collection { get; private set; }
+
+ public CollectionAddedEvent(MovieCollection collection)
+ {
+ Collection = collection;
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Movies/Events/CollectionDeletedEvent.cs b/src/NzbDrone.Core/Movies/Events/CollectionDeletedEvent.cs
new file mode 100644
index 000000000..c03442e61
--- /dev/null
+++ b/src/NzbDrone.Core/Movies/Events/CollectionDeletedEvent.cs
@@ -0,0 +1,15 @@
+using NzbDrone.Common.Messaging;
+using NzbDrone.Core.Movies.Collections;
+
+namespace NzbDrone.Core.Movies.Events
+{
+ public class CollectionDeletedEvent : IEvent
+ {
+ public MovieCollection Collection { get; private set; }
+
+ public CollectionDeletedEvent(MovieCollection collection)
+ {
+ Collection = collection;
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Movies/Events/CollectionEditedEvent.cs b/src/NzbDrone.Core/Movies/Events/CollectionEditedEvent.cs
new file mode 100644
index 000000000..b5453068f
--- /dev/null
+++ b/src/NzbDrone.Core/Movies/Events/CollectionEditedEvent.cs
@@ -0,0 +1,17 @@
+using NzbDrone.Common.Messaging;
+using NzbDrone.Core.Movies.Collections;
+
+namespace NzbDrone.Core.Movies.Events
+{
+ public class CollectionEditedEvent : IEvent
+ {
+ public MovieCollection Collection { get; private set; }
+ public MovieCollection OldCollection { get; private set; }
+
+ public CollectionEditedEvent(MovieCollection collection, MovieCollection oldCollection)
+ {
+ Collection = collection;
+ OldCollection = oldCollection;
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Movies/MonitoringOptions.cs b/src/NzbDrone.Core/Movies/MonitoringOptions.cs
index e6145184d..87519bbb1 100644
--- a/src/NzbDrone.Core/Movies/MonitoringOptions.cs
+++ b/src/NzbDrone.Core/Movies/MonitoringOptions.cs
@@ -1,4 +1,4 @@
-using NzbDrone.Core.Datastore;
+using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.Movies
{
@@ -6,5 +6,13 @@ namespace NzbDrone.Core.Movies
{
public bool IgnoreEpisodesWithFiles { get; set; }
public bool IgnoreEpisodesWithoutFiles { get; set; }
+ public MonitorTypes Monitor { get; set; }
+ }
+
+ public enum MonitorTypes
+ {
+ MovieOnly,
+ MovieAndCollection,
+ None
}
}
diff --git a/src/NzbDrone.Core/Movies/MovieCollection.cs b/src/NzbDrone.Core/Movies/MovieCollection.cs
deleted file mode 100644
index 67500bd25..000000000
--- a/src/NzbDrone.Core/Movies/MovieCollection.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System.Collections.Generic;
-using NzbDrone.Core.Datastore;
-
-namespace NzbDrone.Core.Movies
-{
- public class MovieCollection : IEmbeddedDocument
- {
- public MovieCollection()
- {
- Images = new List();
- }
-
- public string Name { get; set; }
- public int TmdbId { get; set; }
- public List Images { get; set; }
- }
-}
diff --git a/src/NzbDrone.Core/Movies/MovieMetadata.cs b/src/NzbDrone.Core/Movies/MovieMetadata.cs
index b1082b198..193d3b5fa 100644
--- a/src/NzbDrone.Core/Movies/MovieMetadata.cs
+++ b/src/NzbDrone.Core/Movies/MovieMetadata.cs
@@ -31,7 +31,8 @@ namespace NzbDrone.Core.Movies
public int Year { get; set; }
public Ratings Ratings { get; set; }
- public MovieCollection Collection { get; set; }
+ public int CollectionTmdbId { get; set; }
+ public string CollectionTitle { get; set; }
public DateTime? LastInfoSync { get; set; }
public int Runtime { get; set; }
public string Website { get; set; }
diff --git a/src/NzbDrone.Core/Movies/MovieMetadataRepository.cs b/src/NzbDrone.Core/Movies/MovieMetadataRepository.cs
index 78f9b7a29..180db057e 100644
--- a/src/NzbDrone.Core/Movies/MovieMetadataRepository.cs
+++ b/src/NzbDrone.Core/Movies/MovieMetadataRepository.cs
@@ -10,6 +10,7 @@ namespace NzbDrone.Core.Movies
{
MovieMetadata FindByTmdbId(int tmdbId);
List FindById(List tmdbIds);
+ List GetMoviesByCollectionTmdbId(int collectionId);
bool UpsertMany(List data);
}
@@ -33,6 +34,11 @@ namespace NzbDrone.Core.Movies
return Query(x => Enumerable.Contains(tmdbIds, x.TmdbId));
}
+ public List GetMoviesByCollectionTmdbId(int collectionId)
+ {
+ return Query(x => x.CollectionTmdbId == collectionId);
+ }
+
public bool UpsertMany(List data)
{
var existingMetadata = FindById(data.Select(x => x.TmdbId).ToList());
diff --git a/src/NzbDrone.Core/Movies/MovieMetadataService.cs b/src/NzbDrone.Core/Movies/MovieMetadataService.cs
index 172296e32..30a0a9d23 100644
--- a/src/NzbDrone.Core/Movies/MovieMetadataService.cs
+++ b/src/NzbDrone.Core/Movies/MovieMetadataService.cs
@@ -6,6 +6,7 @@ namespace NzbDrone.Core.Movies
{
MovieMetadata Get(int id);
MovieMetadata FindByTmdbId(int tmdbid);
+ List GetMoviesByCollectionTmdbId(int collectionId);
bool Upsert(MovieMetadata movie);
bool UpsertMany(List movies);
}
@@ -24,6 +25,11 @@ namespace NzbDrone.Core.Movies
return _movieMetadataRepository.FindByTmdbId(tmdbid);
}
+ public List GetMoviesByCollectionTmdbId(int collectionId)
+ {
+ return _movieMetadataRepository.GetMoviesByCollectionTmdbId(collectionId);
+ }
+
public MovieMetadata Get(int id)
{
return _movieMetadataRepository.Get(id);
diff --git a/src/NzbDrone.Core/Movies/MovieRepository.cs b/src/NzbDrone.Core/Movies/MovieRepository.cs
index 13a983bc3..5d3acbacd 100644
--- a/src/NzbDrone.Core/Movies/MovieRepository.cs
+++ b/src/NzbDrone.Core/Movies/MovieRepository.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Dapper;
-using NzbDrone.Common.Extensions;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Messaging.Events;
@@ -23,6 +22,7 @@ namespace NzbDrone.Core.Movies
List MoviesBetweenDates(DateTime start, DateTime end, bool includeUnmonitored);
PagingSpec MoviesWithoutFiles(PagingSpec pagingSpec);
List GetMoviesByFileId(int fileId);
+ List GetMoviesByCollectionTmdbId(int collectionId);
void SetFileId(int fileId, int movieId);
PagingSpec MoviesWhereCutoffUnmet(PagingSpec pagingSpec, List qualitiesBelowCutoff);
Movie FindByPath(string path);
@@ -221,6 +221,11 @@ namespace NzbDrone.Core.Movies
return Query(x => x.MovieFileId == fileId);
}
+ public List GetMoviesByCollectionTmdbId(int collectionId)
+ {
+ return Query(x => x.MovieMetadata.Value.CollectionTmdbId == collectionId);
+ }
+
public void SetFileId(int fileId, int movieId)
{
SetFields(new Movie { Id = movieId, MovieFileId = fileId }, movie => movie.MovieFileId);
diff --git a/src/NzbDrone.Core/Movies/MovieScannedHandler.cs b/src/NzbDrone.Core/Movies/MovieScannedHandler.cs
index 41a3a0885..63fe3c7f6 100644
--- a/src/NzbDrone.Core/Movies/MovieScannedHandler.cs
+++ b/src/NzbDrone.Core/Movies/MovieScannedHandler.cs
@@ -4,6 +4,7 @@ using NzbDrone.Core.IndexerSearch;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
+using NzbDrone.Core.Movies.Collections;
namespace NzbDrone.Core.Movies
{
@@ -11,15 +12,18 @@ namespace NzbDrone.Core.Movies
IHandle
{
private readonly IMovieService _movieService;
+ private readonly IMovieCollectionService _collectionService;
private readonly IManageCommandQueue _commandQueueManager;
private readonly Logger _logger;
public MovieScannedHandler(IMovieService movieService,
+ IMovieCollectionService collectionService,
IManageCommandQueue commandQueueManager,
Logger logger)
{
_movieService = movieService;
+ _collectionService = collectionService;
_commandQueueManager = commandQueueManager;
_logger = logger;
}
@@ -38,6 +42,14 @@ namespace NzbDrone.Core.Movies
_commandQueueManager.Push(new MoviesSearchCommand { MovieIds = new List { movie.Id } });
}
+ if (movie.AddOptions.Monitor == MonitorTypes.MovieAndCollection && movie.MovieMetadata.Value.CollectionTmdbId > 0)
+ {
+ var collection = _collectionService.FindByTmdbId(movie.MovieMetadata.Value.CollectionTmdbId);
+ collection.Monitored = true;
+
+ _collectionService.UpdateCollection(collection);
+ }
+
movie.AddOptions = null;
_movieService.RemoveAddOptions(movie);
}
diff --git a/src/NzbDrone.Core/Movies/MovieService.cs b/src/NzbDrone.Core/Movies/MovieService.cs
index 4373cb364..ef01187d9 100644
--- a/src/NzbDrone.Core/Movies/MovieService.cs
+++ b/src/NzbDrone.Core/Movies/MovieService.cs
@@ -34,6 +34,7 @@ namespace NzbDrone.Core.Movies
List AllMovieTmdbIds();
bool MovieExists(Movie movie);
List GetMoviesByFileId(int fileId);
+ List GetMoviesByCollectionTmdbId(int collectionId);
List GetMoviesBetweenDates(DateTime start, DateTime end, bool includeUnmonitored);
PagingSpec MoviesWithoutFiles(PagingSpec pagingSpec);
void SetFileId(Movie movie, MovieFile movieFile);
@@ -88,15 +89,17 @@ namespace NzbDrone.Core.Movies
public Movie AddMovie(Movie newMovie)
{
- _movieRepository.Insert(newMovie);
- _eventAggregator.PublishEvent(new MovieAddedEvent(GetMovie(newMovie.Id)));
+ var movie = _movieRepository.Insert(newMovie);
- return newMovie;
+ _eventAggregator.PublishEvent(new MovieAddedEvent(GetMovie(movie.Id)));
+
+ return movie;
}
public List AddMovies(List newMovies)
{
_movieRepository.InsertMany(newMovies);
+
_eventAggregator.PublishEvent(new MoviesImportedEvent(newMovies.Select(s => s.Id).ToList()));
return newMovies;
@@ -293,6 +296,11 @@ namespace NzbDrone.Core.Movies
return _movieRepository.GetMoviesByFileId(fileId);
}
+ public List GetMoviesByCollectionTmdbId(int collectionId)
+ {
+ return _movieRepository.GetMoviesByCollectionTmdbId(collectionId);
+ }
+
public List GetMoviesBetweenDates(DateTime start, DateTime end, bool includeUnmonitored)
{
var movies = _movieRepository.MoviesBetweenDates(start.ToUniversalTime(), end.ToUniversalTime(), includeUnmonitored);
diff --git a/src/NzbDrone.Core/Movies/RefreshCollectionService.cs b/src/NzbDrone.Core/Movies/RefreshCollectionService.cs
new file mode 100644
index 000000000..671471b4e
--- /dev/null
+++ b/src/NzbDrone.Core/Movies/RefreshCollectionService.cs
@@ -0,0 +1,159 @@
+using System;
+using System.Linq;
+using NLog;
+using NzbDrone.Common.Instrumentation.Extensions;
+using NzbDrone.Core.Exceptions;
+using NzbDrone.Core.Messaging.Commands;
+using NzbDrone.Core.Messaging.Events;
+using NzbDrone.Core.MetadataSource;
+using NzbDrone.Core.Movies.Collections;
+using NzbDrone.Core.Movies.Commands;
+using NzbDrone.Core.Movies.Events;
+
+namespace NzbDrone.Core.Movies
+{
+ public class RefreshCollectionService : IExecute, IHandle
+ {
+ private readonly IProvideMovieInfo _movieInfo;
+ private readonly IMovieCollectionService _collectionService;
+ private readonly IMovieService _movieService;
+ private readonly IMovieMetadataService _movieMetadataService;
+ private readonly IAddMovieService _addMovieService;
+
+ private readonly Logger _logger;
+
+ public RefreshCollectionService(IProvideMovieInfo movieInfo,
+ IMovieCollectionService collectionService,
+ IMovieService movieService,
+ IMovieMetadataService movieMetadataService,
+ IAddMovieService addMovieService,
+ Logger logger)
+ {
+ _movieInfo = movieInfo;
+ _collectionService = collectionService;
+ _movieService = movieService;
+ _movieMetadataService = movieMetadataService;
+ _addMovieService = addMovieService;
+ _logger = logger;
+ }
+
+ private MovieCollection RefreshCollectionInfo(int collectionId)
+ {
+ // Get the movie before updating, that way any changes made to the movie after the refresh started,
+ // but before this movie was refreshed won't be lost.
+ var collection = _collectionService.GetCollection(collectionId);
+
+ _logger.ProgressInfo("Updating info for {0}", collection.Title);
+
+ MovieCollection collectionInfo;
+
+ try
+ {
+ collectionInfo = _movieInfo.GetCollectionInfo(collection.TmdbId);
+ }
+ catch (MovieNotFoundException)
+ {
+ _collectionService.RemoveCollection(collection);
+ _logger.Debug("Removing collection not present on TMDb for {0}", collection.Title);
+
+ throw;
+ }
+
+ collection.Title = collectionInfo.Title;
+ collection.Overview = collectionInfo.Overview;
+ collection.CleanTitle = collectionInfo.CleanTitle;
+ collection.SortTitle = collectionInfo.SortTitle;
+ collection.LastInfoSync = DateTime.UtcNow;
+ collection.Images = collectionInfo.Images;
+
+ collectionInfo.Movies.ForEach(x => x.CollectionTmdbId = collection.TmdbId);
+ _movieMetadataService.UpsertMany(collectionInfo.Movies);
+
+ _logger.Debug("Finished collection refresh for {0}", collection.Title);
+
+ _collectionService.UpdateCollection(collection);
+
+ return collection;
+ }
+
+ public bool ShouldRefresh(MovieCollection collection)
+ {
+ if (collection.LastInfoSync == null || collection.LastInfoSync < DateTime.UtcNow.AddDays(-15))
+ {
+ _logger.Trace("Collection {0} last updated more than 15 days ago, should refresh.", collection.Title);
+ return true;
+ }
+
+ if (collection.LastInfoSync >= DateTime.UtcNow.AddHours(-6))
+ {
+ _logger.Trace("Collection {0} last updated less than 6 hours ago, should not be refreshed.", collection.Title);
+ return false;
+ }
+
+ return false;
+ }
+
+ private void SyncCollectionMovies(MovieCollection collection)
+ {
+ if (collection.Monitored)
+ {
+ var existingMovies = _movieService.AllMovieTmdbIds();
+ var collectionMovies = _movieMetadataService.GetMoviesByCollectionTmdbId(collection.TmdbId);
+
+ _addMovieService.AddMovies(collectionMovies.Where(m => !existingMovies.Contains(m.TmdbId)).Select(m => new Movie
+ {
+ TmdbId = m.TmdbId,
+ Title = m.Title,
+ ProfileId = collection.QualityProfileId,
+ RootFolderPath = collection.RootFolderPath,
+ MinimumAvailability = collection.MinimumAvailability,
+ AddOptions = new AddMovieOptions
+ {
+ SearchForMovie = collection.SearchOnAdd
+ },
+ Monitored = true
+ }).ToList());
+ }
+ }
+
+ public void Execute(RefreshCollectionsCommand message)
+ {
+ if (message.CollectionIds.Any())
+ {
+ foreach (var collectionId in message.CollectionIds)
+ {
+ var newCollection = RefreshCollectionInfo(collectionId);
+ SyncCollectionMovies(newCollection);
+ }
+ }
+ else
+ {
+ var allCollections = _collectionService.GetAllCollections().OrderBy(c => c.SortTitle).ToList();
+
+ foreach (var collection in allCollections)
+ {
+ try
+ {
+ var newCollection = collection;
+
+ if (ShouldRefresh(collection) || message.Trigger == CommandTrigger.Manual)
+ {
+ newCollection = RefreshCollectionInfo(collection.Id);
+ }
+
+ SyncCollectionMovies(newCollection);
+ }
+ catch (MovieNotFoundException)
+ {
+ _logger.Error("Collection '{0}' (TMDb {1}) was not found, it may have been removed from The Movie Database.", collection.Title, collection.TmdbId);
+ }
+ }
+ }
+ }
+
+ public void Handle(CollectionEditedEvent message)
+ {
+ SyncCollectionMovies(message.Collection);
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Movies/RefreshMovieService.cs b/src/NzbDrone.Core/Movies/RefreshMovieService.cs
index 40a08bafe..6804cd69a 100644
--- a/src/NzbDrone.Core/Movies/RefreshMovieService.cs
+++ b/src/NzbDrone.Core/Movies/RefreshMovieService.cs
@@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
using NLog;
-using NzbDrone.Common.Extensions;
using NzbDrone.Common.Instrumentation.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Exceptions;
@@ -12,10 +10,12 @@ using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.Movies.AlternativeTitles;
+using NzbDrone.Core.Movies.Collections;
using NzbDrone.Core.Movies.Commands;
using NzbDrone.Core.Movies.Credits;
using NzbDrone.Core.Movies.Events;
using NzbDrone.Core.Movies.Translations;
+using NzbDrone.Core.RootFolders;
namespace NzbDrone.Core.Movies
{
@@ -23,7 +23,9 @@ namespace NzbDrone.Core.Movies
{
private readonly IProvideMovieInfo _movieInfo;
private readonly IMovieService _movieService;
+ private readonly IAddMovieCollectionService _movieCollectionService;
private readonly IMovieMetadataService _movieMetadataService;
+ private readonly IRootFolderService _folderService;
private readonly IMovieTranslationService _movieTranslationService;
private readonly IAlternativeTitleService _titleService;
private readonly ICreditService _creditService;
@@ -36,7 +38,9 @@ namespace NzbDrone.Core.Movies
public RefreshMovieService(IProvideMovieInfo movieInfo,
IMovieService movieService,
+ IAddMovieCollectionService movieCollectionService,
IMovieMetadataService movieMetadataService,
+ IRootFolderService folderService,
IMovieTranslationService movieTranslationService,
IAlternativeTitleService titleService,
ICreditService creditService,
@@ -48,7 +52,9 @@ namespace NzbDrone.Core.Movies
{
_movieInfo = movieInfo;
_movieService = movieService;
+ _movieCollectionService = movieCollectionService;
_movieMetadataService = movieMetadataService;
+ _folderService = folderService;
_movieTranslationService = movieTranslationService;
_titleService = titleService;
_creditService = creditService;
@@ -105,7 +111,6 @@ namespace NzbDrone.Core.Movies
movieMetadata.LastInfoSync = DateTime.UtcNow;
movieMetadata.Runtime = movieInfo.Runtime;
movieMetadata.Ratings = movieInfo.Ratings;
- movieMetadata.Collection = movieInfo.Collection;
//movie.Genres = movieInfo.Genres;
movieMetadata.Certification = movieInfo.Certification;
@@ -124,6 +129,24 @@ namespace NzbDrone.Core.Movies
movieMetadata.Recommendations = movieInfo.Recommendations;
movieMetadata.Popularity = movieInfo.Popularity;
+ // add collection
+ if (movieInfo.CollectionTmdbId > 0)
+ {
+ var newCollection = _movieCollectionService.AddMovieCollection(new MovieCollection
+ {
+ TmdbId = movieInfo.CollectionTmdbId,
+ Title = movieInfo.CollectionTitle,
+ Monitored = movie.AddOptions?.Monitor == MonitorTypes.MovieAndCollection,
+ SearchOnAdd = movie.AddOptions?.SearchForMovie ?? false,
+ QualityProfileId = movie.ProfileId,
+ MinimumAvailability = movie.MinimumAvailability,
+ RootFolderPath = _folderService.GetBestRootFolderPath(movie.Path)
+ });
+
+ movieMetadata.CollectionTmdbId = newCollection.TmdbId;
+ movieMetadata.CollectionTitle = newCollection.Title;
+ }
+
movieMetadata.AlternativeTitles = _titleService.UpdateTitles(movieInfo.AlternativeTitles, movieMetadata);
_movieTranslationService.UpdateTranslations(movieInfo.Translations, movieMetadata);
diff --git a/src/NzbDrone.Core/Movies/Translations/MovieTranslationService.cs b/src/NzbDrone.Core/Movies/Translations/MovieTranslationService.cs
index c50750835..f531ea55d 100644
--- a/src/NzbDrone.Core/Movies/Translations/MovieTranslationService.cs
+++ b/src/NzbDrone.Core/Movies/Translations/MovieTranslationService.cs
@@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using NLog;
-using NzbDrone.Common.Extensions;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Movies.Events;
diff --git a/src/NzbDrone.Core/Notifications/DeleteMessage.cs b/src/NzbDrone.Core/Notifications/DeleteMessage.cs
index ec700f7b4..b2e2ca669 100644
--- a/src/NzbDrone.Core/Notifications/DeleteMessage.cs
+++ b/src/NzbDrone.Core/Notifications/DeleteMessage.cs
@@ -1,4 +1,3 @@
-using System.Collections.Generic;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Movies;
diff --git a/src/NzbDrone.Core/Notifications/Email/Email.cs b/src/NzbDrone.Core/Notifications/Email/Email.cs
index 71b787447..07a232120 100644
--- a/src/NzbDrone.Core/Notifications/Email/Email.cs
+++ b/src/NzbDrone.Core/Notifications/Email/Email.cs
@@ -8,7 +8,6 @@ using MimeKit;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http.Dispatchers;
-using NzbDrone.Core.Security;
namespace NzbDrone.Core.Notifications.Email
{
diff --git a/src/NzbDrone.Core/Notifications/MovieDeleteMessage.cs b/src/NzbDrone.Core/Notifications/MovieDeleteMessage.cs
index 8c89d0165..de3294057 100644
--- a/src/NzbDrone.Core/Notifications/MovieDeleteMessage.cs
+++ b/src/NzbDrone.Core/Notifications/MovieDeleteMessage.cs
@@ -1,4 +1,3 @@
-using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Movies;
namespace NzbDrone.Core.Notifications
diff --git a/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrProxy.cs b/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrProxy.cs
index 4b9397749..9afa37927 100644
--- a/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrProxy.cs
+++ b/src/NzbDrone.Core/Notifications/Notifiarr/NotifiarrProxy.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Specialized;
-using System.Net;
using FluentValidation.Results;
using NLog;
using NzbDrone.Common.Http;
diff --git a/src/NzbDrone.Core/Notifications/NotificationBase.cs b/src/NzbDrone.Core/Notifications/NotificationBase.cs
index 9b73e1a43..e99d4e1ed 100644
--- a/src/NzbDrone.Core/Notifications/NotificationBase.cs
+++ b/src/NzbDrone.Core/Notifications/NotificationBase.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using FluentValidation.Results;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Movies;
diff --git a/src/NzbDrone.Core/Notifications/NotificationFactory.cs b/src/NzbDrone.Core/Notifications/NotificationFactory.cs
index c121a8734..51321cf07 100644
--- a/src/NzbDrone.Core/Notifications/NotificationFactory.cs
+++ b/src/NzbDrone.Core/Notifications/NotificationFactory.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
-using NzbDrone.Common.Composition;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.ThingiProvider;
diff --git a/src/NzbDrone.Core/Notifications/Simplepush/SimplepushProxy.cs b/src/NzbDrone.Core/Notifications/Simplepush/SimplepushProxy.cs
index 5254b73de..f0f6788f2 100644
--- a/src/NzbDrone.Core/Notifications/Simplepush/SimplepushProxy.cs
+++ b/src/NzbDrone.Core/Notifications/Simplepush/SimplepushProxy.cs
@@ -1,7 +1,6 @@
using System;
using FluentValidation.Results;
using NLog;
-using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
namespace NzbDrone.Core.Notifications.Simplepush
diff --git a/src/NzbDrone.Core/Notifications/Simplepush/SimplepushSettings.cs b/src/NzbDrone.Core/Notifications/Simplepush/SimplepushSettings.cs
index 92daff3b4..af8b211ef 100644
--- a/src/NzbDrone.Core/Notifications/Simplepush/SimplepushSettings.cs
+++ b/src/NzbDrone.Core/Notifications/Simplepush/SimplepushSettings.cs
@@ -1,4 +1,3 @@
-using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.ThingiProvider;
diff --git a/src/NzbDrone.Core/Notifications/Slack/Slack.cs b/src/NzbDrone.Core/Notifications/Slack/Slack.cs
index 97f59b351..d3f1e52a9 100644
--- a/src/NzbDrone.Core/Notifications/Slack/Slack.cs
+++ b/src/NzbDrone.Core/Notifications/Slack/Slack.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
using FluentValidation.Results;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.MediaFiles;
diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookApplicationUpdatePayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookApplicationUpdatePayload.cs
index e05be69bc..66a6ff382 100644
--- a/src/NzbDrone.Core/Notifications/Webhook/WebhookApplicationUpdatePayload.cs
+++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookApplicationUpdatePayload.cs
@@ -1,5 +1,3 @@
-using NzbDrone.Core.HealthCheck;
-
namespace NzbDrone.Core.Notifications.Webhook
{
public class WebhookApplicationUpdatePayload : WebhookPayload
diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieDeletePayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieDeletePayload.cs
index 8540110f5..4b111ef26 100644
--- a/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieDeletePayload.cs
+++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieDeletePayload.cs
@@ -1,5 +1,3 @@
-using System.Collections.Generic;
-
namespace NzbDrone.Core.Notifications.Webhook
{
public class WebhookMovieDeletePayload : WebhookPayload
diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFileDeletePayload.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFileDeletePayload.cs
index 851fa285c..c3c85edbd 100644
--- a/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFileDeletePayload.cs
+++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFileDeletePayload.cs
@@ -1,4 +1,3 @@
-using System.Collections.Generic;
using NzbDrone.Core.MediaFiles;
namespace NzbDrone.Core.Notifications.Webhook
diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs
index ababf2787..c62ef3ebe 100644
--- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs
+++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs
@@ -7,7 +7,6 @@ using System.Linq;
using System.Text.RegularExpressions;
using NLog;
using NzbDrone.Common.EnsureThat;
-using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.MediaFiles;
@@ -268,7 +267,7 @@ namespace NzbDrone.Core.Organizer
tokenHandlers["{Movie CleanOriginalTitle}"] = m => CleanTitle(movie.MovieMetadata.Value.OriginalTitle) ?? string.Empty;
tokenHandlers["{Movie Certification}"] = m => movie.MovieMetadata.Value.Certification ?? string.Empty;
- tokenHandlers["{Movie Collection}"] = m => movie.MovieMetadata.Value.Collection?.Name ?? string.Empty;
+ tokenHandlers["{Movie Collection}"] = m => movie.MovieMetadata.Value.CollectionTitle ?? string.Empty;
}
private string GetLanguageTitle(Movie movie, string isoCodes)
diff --git a/src/NzbDrone.Core/Organizer/FileNameSampleService.cs b/src/NzbDrone.Core/Organizer/FileNameSampleService.cs
index 70e4aeecb..ff887adf2 100644
--- a/src/NzbDrone.Core/Organizer/FileNameSampleService.cs
+++ b/src/NzbDrone.Core/Organizer/FileNameSampleService.cs
@@ -54,7 +54,8 @@ namespace NzbDrone.Core.Organizer
{
Title = "The Movie: Title",
OriginalTitle = "The Original Movie Title",
- Collection = new MovieCollection { Name = "The Movie Collection", TmdbId = 123654 },
+ CollectionTitle = "The Movie Collection",
+ CollectionTmdbId = 123654,
Certification = "R",
Year = 2010,
ImdbId = "tt0066921",
diff --git a/src/NzbDrone.Core/Parser/IsoLanguages.cs b/src/NzbDrone.Core/Parser/IsoLanguages.cs
index 1469a5a60..5bd683176 100644
--- a/src/NzbDrone.Core/Parser/IsoLanguages.cs
+++ b/src/NzbDrone.Core/Parser/IsoLanguages.cs
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Linq;
-using System.Runtime.InteropServices.ComTypes;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Organizer;
diff --git a/src/NzbDrone.Core/Parser/LanguageParser.cs b/src/NzbDrone.Core/Parser/LanguageParser.cs
index 69e8b9f20..991531ede 100644
--- a/src/NzbDrone.Core/Parser/LanguageParser.cs
+++ b/src/NzbDrone.Core/Parser/LanguageParser.cs
@@ -4,7 +4,6 @@ using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using NLog;
-using NzbDrone.Common.Extensions;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Core.Languages;
diff --git a/src/NzbDrone.Core/Profiles/ProfileService.cs b/src/NzbDrone.Core/Profiles/ProfileService.cs
index a21478edd..09e79ed4a 100644
--- a/src/NzbDrone.Core/Profiles/ProfileService.cs
+++ b/src/NzbDrone.Core/Profiles/ProfileService.cs
@@ -8,6 +8,7 @@ using NzbDrone.Core.Languages;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Movies;
+using NzbDrone.Core.Movies.Collections;
using NzbDrone.Core.Qualities;
namespace NzbDrone.Core.Profiles
@@ -33,18 +34,21 @@ namespace NzbDrone.Core.Profiles
private readonly ICustomFormatService _formatService;
private readonly IMovieService _movieService;
private readonly IImportListFactory _importListFactory;
+ private readonly IMovieCollectionService _collectionService;
private readonly Logger _logger;
public ProfileService(IProfileRepository profileRepository,
ICustomFormatService formatService,
IMovieService movieService,
IImportListFactory importListFactory,
+ IMovieCollectionService collectionService,
Logger logger)
{
_profileRepository = profileRepository;
_formatService = formatService;
_movieService = movieService;
_importListFactory = importListFactory;
+ _collectionService = collectionService;
_logger = logger;
}
@@ -60,7 +64,7 @@ namespace NzbDrone.Core.Profiles
public void Delete(int id)
{
- if (_movieService.GetAllMovies().Any(c => c.ProfileId == id) || _importListFactory.All().Any(c => c.ProfileId == id))
+ if (_movieService.GetAllMovies().Any(c => c.ProfileId == id) || _importListFactory.All().Any(c => c.ProfileId == id) || _collectionService.GetAllCollections().Any(c => c.QualityProfileId == id))
{
throw new ProfileInUseException(id);
}
diff --git a/src/NzbDrone.Core/ThingiProvider/ProviderFactory.cs b/src/NzbDrone.Core/ThingiProvider/ProviderFactory.cs
index dd51a9d7a..c1a93c019 100644
--- a/src/NzbDrone.Core/ThingiProvider/ProviderFactory.cs
+++ b/src/NzbDrone.Core/ThingiProvider/ProviderFactory.cs
@@ -4,7 +4,6 @@ using System.Linq;
using FluentValidation.Results;
using Microsoft.Extensions.DependencyInjection;
using NLog;
-using NzbDrone.Common.Composition;
using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.ThingiProvider.Events;
diff --git a/src/NzbDrone.Core/Update/History/UpdateHistoryRepository.cs b/src/NzbDrone.Core/Update/History/UpdateHistoryRepository.cs
index 40bd68963..fe5e259b5 100644
--- a/src/NzbDrone.Core/Update/History/UpdateHistoryRepository.cs
+++ b/src/NzbDrone.Core/Update/History/UpdateHistoryRepository.cs
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging.Events;
diff --git a/src/NzbDrone.Core/Update/RecentUpdateProvider.cs b/src/NzbDrone.Core/Update/RecentUpdateProvider.cs
index 42b338f5f..4796a68e2 100644
--- a/src/NzbDrone.Core/Update/RecentUpdateProvider.cs
+++ b/src/NzbDrone.Core/Update/RecentUpdateProvider.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Update.History;
diff --git a/src/Radarr.Api.V3/Collections/CollectionController.cs b/src/Radarr.Api.V3/Collections/CollectionController.cs
new file mode 100644
index 000000000..41f9823db
--- /dev/null
+++ b/src/Radarr.Api.V3/Collections/CollectionController.cs
@@ -0,0 +1,128 @@
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.AspNetCore.Mvc;
+using NzbDrone.Core.Datastore.Events;
+using NzbDrone.Core.Messaging.Events;
+using NzbDrone.Core.Movies;
+using NzbDrone.Core.Movies.Collections;
+using NzbDrone.Core.Movies.Events;
+using NzbDrone.Core.Organizer;
+using NzbDrone.SignalR;
+using Radarr.Http;
+using Radarr.Http.REST;
+using Radarr.Http.REST.Attributes;
+
+namespace Radarr.Api.V3.Collections
+{
+ [V3ApiController]
+ public class CollectionController : RestControllerWithSignalR,
+ IHandle,
+ IHandle,
+ IHandle
+ {
+ private readonly IMovieCollectionService _collectionService;
+ private readonly IMovieService _movieService;
+ private readonly IMovieMetadataService _movieMetadataService;
+ private readonly IBuildFileNames _fileNameBuilder;
+
+ public CollectionController(IBroadcastSignalRMessage signalRBroadcaster,
+ IMovieCollectionService collectionService,
+ IMovieService movieService,
+ IMovieMetadataService movieMetadataService,
+ IBuildFileNames fileNameBuilder)
+ : base(signalRBroadcaster)
+ {
+ _collectionService = collectionService;
+ _movieService = movieService;
+ _movieMetadataService = movieMetadataService;
+ _fileNameBuilder = fileNameBuilder;
+ }
+
+ protected override CollectionResource GetResourceById(int id)
+ {
+ return MapToResource(_collectionService.GetCollection(id));
+ }
+
+ [HttpGet]
+ public List GetCollections()
+ {
+ return _collectionService.GetAllCollections().Select(c => MapToResource(c)).ToList();
+ }
+
+ [RestPutById]
+ public ActionResult UpdateCollection(CollectionResource collectionResource)
+ {
+ var collection = _collectionService.GetCollection(collectionResource.Id);
+
+ var model = collectionResource.ToModel(collection);
+
+ var updatedMovie = _collectionService.UpdateCollection(model);
+
+ return Accepted(updatedMovie.Id);
+ }
+
+ [HttpPut]
+ public ActionResult UpdateCollections(CollectionUpdateResource collectionResources)
+ {
+ var collectionsToUpdate = _collectionService.GetCollections(collectionResources.Collections.Select(c => c.Id));
+ var update = new List();
+
+ foreach (var c in collectionResources.Collections)
+ {
+ var collection = collectionsToUpdate.Single(n => n.Id == c.Id);
+
+ if (c.Monitored.HasValue)
+ {
+ collection.Monitored = c.Monitored.Value;
+ }
+
+ if (collectionResources.MonitorMovies.HasValue)
+ {
+ var movies = _movieService.GetMoviesByCollectionTmdbId(collection.TmdbId);
+
+ movies.ForEach(c => c.Monitored = collectionResources.MonitorMovies.Value);
+
+ _movieService.UpdateMovie(movies, true);
+ }
+
+ var updatedCollection = _collectionService.UpdateCollection(collection);
+ update.Add(updatedCollection.ToResource());
+ }
+
+ return Accepted(update);
+ }
+
+ private CollectionResource MapToResource(MovieCollection collection)
+ {
+ var resource = collection.ToResource();
+
+ foreach (var movie in _movieMetadataService.GetMoviesByCollectionTmdbId(collection.TmdbId))
+ {
+ var movieResource = movie.ToResource();
+ movieResource.Folder = _fileNameBuilder.GetMovieFolder(new Movie { Title = movie.Title, Year = movie.Year, ImdbId = movie.ImdbId, TmdbId = movie.TmdbId });
+
+ resource.Movies.Add(movieResource);
+ }
+
+ return resource;
+ }
+
+ [NonAction]
+ public void Handle(CollectionAddedEvent message)
+ {
+ BroadcastResourceChange(ModelAction.Created, MapToResource(message.Collection));
+ }
+
+ [NonAction]
+ public void Handle(CollectionEditedEvent message)
+ {
+ BroadcastResourceChange(ModelAction.Updated, MapToResource(message.Collection));
+ }
+
+ [NonAction]
+ public void Handle(CollectionDeletedEvent message)
+ {
+ BroadcastResourceChange(ModelAction.Deleted, MapToResource(message.Collection));
+ }
+ }
+}
diff --git a/src/Radarr.Api.V3/Collections/CollectionMovieResource.cs b/src/Radarr.Api.V3/Collections/CollectionMovieResource.cs
new file mode 100644
index 000000000..d7cea6503
--- /dev/null
+++ b/src/Radarr.Api.V3/Collections/CollectionMovieResource.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using NzbDrone.Core.MediaCover;
+using NzbDrone.Core.Movies;
+using NzbDrone.Core.Movies.Collections;
+
+namespace Radarr.Api.V3.Collections
+{
+ public class CollectionMovieResource
+ {
+ public int TmdbId { get; set; }
+ public string ImdbId { get; set; }
+ public string Title { get; set; }
+ public string CleanTitle { get; set; }
+ public string SortTitle { get; set; }
+ public string Overview { get; set; }
+ public int Runtime { get; set; }
+ public List Images { get; set; }
+ public int Year { get; set; }
+ public Ratings Ratings { get; set; }
+ public List Genres { get; set; }
+ public string Folder { get; set; }
+ }
+
+ public static class CollectionMovieResourceMapper
+ {
+ public static CollectionMovieResource ToResource(this MovieMetadata model)
+ {
+ if (model == null)
+ {
+ return null;
+ }
+
+ return new CollectionMovieResource
+ {
+ TmdbId = model.TmdbId,
+ Title = model.Title,
+ Overview = model.Overview,
+ SortTitle = model.SortTitle,
+ Images = model.Images,
+ ImdbId = model.ImdbId,
+ Ratings = model.Ratings,
+ Runtime = model.Runtime,
+ CleanTitle = model.CleanTitle,
+ Genres = model.Genres,
+ Year = model.Year
+ };
+ }
+ }
+}
diff --git a/src/Radarr.Api.V3/Collections/CollectionResource.cs b/src/Radarr.Api.V3/Collections/CollectionResource.cs
new file mode 100644
index 000000000..88b6b1bdf
--- /dev/null
+++ b/src/Radarr.Api.V3/Collections/CollectionResource.cs
@@ -0,0 +1,91 @@
+using System.Collections.Generic;
+using System.Linq;
+using NzbDrone.Core.MediaCover;
+using NzbDrone.Core.Movies;
+using NzbDrone.Core.Movies.Collections;
+using Radarr.Http.REST;
+
+namespace Radarr.Api.V3.Collections
+{
+ public class CollectionResource : RestResource
+ {
+ public CollectionResource()
+ {
+ Movies = new List();
+ }
+
+ public string Title { get; set; }
+ public string SortTitle { get; set; }
+ public int TmdbId { get; set; }
+ public List Images { get; set; }
+ public string Overview { get; set; }
+ public bool Monitored { get; set; }
+ public string RootFolderPath { get; set; }
+ public int QualityProfileId { get; set; }
+ public bool SearchOnAdd { get; set; }
+ public MovieStatusType MinimumAvailability { get; set; }
+ public List Movies { get; set; }
+ }
+
+ public static class CollectionResourceMapper
+ {
+ public static CollectionResource ToResource(this MovieCollection model)
+ {
+ if (model == null)
+ {
+ return null;
+ }
+
+ return new CollectionResource
+ {
+ Id = model.Id,
+ TmdbId = model.TmdbId,
+ Title = model.Title,
+ Overview = model.Overview,
+ SortTitle = model.SortTitle,
+ Monitored = model.Monitored,
+ Images = model.Images,
+ QualityProfileId = model.QualityProfileId,
+ RootFolderPath = model.RootFolderPath,
+ MinimumAvailability = model.MinimumAvailability,
+ SearchOnAdd = model.SearchOnAdd
+ };
+ }
+
+ public static List ToResource(this IEnumerable collections)
+ {
+ return collections.Select(ToResource).ToList();
+ }
+
+ public static MovieCollection ToModel(this CollectionResource resource)
+ {
+ if (resource == null)
+ {
+ return null;
+ }
+
+ return new MovieCollection
+ {
+ Id = resource.Id,
+ Title = resource.Title,
+ TmdbId = resource.TmdbId,
+ SortTitle = resource.SortTitle,
+ Overview = resource.Overview,
+ Monitored = resource.Monitored,
+ QualityProfileId = resource.QualityProfileId,
+ RootFolderPath = resource.RootFolderPath,
+ SearchOnAdd = resource.SearchOnAdd,
+ MinimumAvailability = resource.MinimumAvailability
+ };
+ }
+
+ public static MovieCollection ToModel(this CollectionResource resource, MovieCollection collection)
+ {
+ var updatedmovie = resource.ToModel();
+
+ collection.ApplyChanges(updatedmovie);
+
+ return collection;
+ }
+ }
+}
diff --git a/src/Radarr.Api.V3/Collections/CollectionUpdateCollectionResource.cs b/src/Radarr.Api.V3/Collections/CollectionUpdateCollectionResource.cs
new file mode 100644
index 000000000..36fc06875
--- /dev/null
+++ b/src/Radarr.Api.V3/Collections/CollectionUpdateCollectionResource.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Radarr.Api.V3.Collections
+{
+ public class CollectionUpdateCollectionResource
+ {
+ public int Id { get; set; }
+ public bool? Monitored { get; set; }
+ }
+}
diff --git a/src/Radarr.Api.V3/Collections/CollectionUpdateResource.cs b/src/Radarr.Api.V3/Collections/CollectionUpdateResource.cs
new file mode 100644
index 000000000..05e269814
--- /dev/null
+++ b/src/Radarr.Api.V3/Collections/CollectionUpdateResource.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+
+namespace Radarr.Api.V3.Collections
+{
+ public class CollectionUpdateResource
+ {
+ public List Collections { get; set; }
+ public bool? MonitorMovies { get; set; }
+ }
+}
diff --git a/src/Radarr.Api.V3/ImportLists/ImportListMoviesResource.cs b/src/Radarr.Api.V3/ImportLists/ImportListMoviesResource.cs
index c4c71bb42..687fc964e 100644
--- a/src/Radarr.Api.V3/ImportLists/ImportListMoviesResource.cs
+++ b/src/Radarr.Api.V3/ImportLists/ImportListMoviesResource.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using NzbDrone.Core.ImportLists.ImportListMovies;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Movies;
+using NzbDrone.Core.Movies.Collections;
using Radarr.Http.REST;
namespace Radarr.Api.V3.ImportLists
@@ -75,8 +76,8 @@ namespace Radarr.Api.V3.ImportLists
Genres = model.MovieMetadata.Value.Genres,
Ratings = model.MovieMetadata.Value.Ratings,
YouTubeTrailerId = model.MovieMetadata.Value.YouTubeTrailerId,
- Studio = model.MovieMetadata.Value.Studio,
- Collection = model.MovieMetadata.Value.Collection
+ Collection = new MovieCollection { Title = model.MovieMetadata.Value.CollectionTitle, TmdbId = model.MovieMetadata.Value.CollectionTmdbId },
+ Studio = model.MovieMetadata.Value.Studio
};
}
@@ -111,7 +112,7 @@ namespace Radarr.Api.V3.ImportLists
Ratings = model.MovieMetadata.Value.Ratings,
YouTubeTrailerId = model.MovieMetadata.Value.YouTubeTrailerId,
Studio = model.MovieMetadata.Value.Studio,
- Collection = model.MovieMetadata.Value.Collection,
+ Collection = new MovieCollection { Title = model.MovieMetadata.Value.CollectionTitle, TmdbId = model.MovieMetadata.Value.CollectionTmdbId },
Lists = new HashSet { model.ListId }
};
}
diff --git a/src/Radarr.Api.V3/ImportLists/ImportListResource.cs b/src/Radarr.Api.V3/ImportLists/ImportListResource.cs
index 08019e064..a97f3007d 100644
--- a/src/Radarr.Api.V3/ImportLists/ImportListResource.cs
+++ b/src/Radarr.Api.V3/ImportLists/ImportListResource.cs
@@ -7,7 +7,7 @@ namespace Radarr.Api.V3.ImportLists
{
public bool Enabled { get; set; }
public bool EnableAuto { get; set; }
- public bool ShouldMonitor { get; set; }
+ public MonitorTypes Monitor { get; set; }
public string RootFolderPath { get; set; }
public int QualityProfileId { get; set; }
public bool SearchOnAdd { get; set; }
@@ -29,7 +29,7 @@ namespace Radarr.Api.V3.ImportLists
resource.Enabled = definition.Enabled;
resource.EnableAuto = definition.EnableAuto;
- resource.ShouldMonitor = definition.ShouldMonitor;
+ resource.Monitor = definition.Monitor;
resource.SearchOnAdd = definition.SearchOnAdd;
resource.RootFolderPath = definition.RootFolderPath;
resource.QualityProfileId = definition.ProfileId;
@@ -51,7 +51,7 @@ namespace Radarr.Api.V3.ImportLists
definition.Enabled = resource.Enabled;
definition.EnableAuto = resource.EnableAuto;
- definition.ShouldMonitor = resource.ShouldMonitor;
+ definition.Monitor = resource.Monitor;
definition.SearchOnAdd = resource.SearchOnAdd;
definition.RootFolderPath = resource.RootFolderPath;
definition.ProfileId = resource.QualityProfileId;
diff --git a/src/Radarr.Api.V3/Movies/MovieResource.cs b/src/Radarr.Api.V3/Movies/MovieResource.cs
index 605c265c9..047349e37 100644
--- a/src/Radarr.Api.V3/Movies/MovieResource.cs
+++ b/src/Radarr.Api.V3/Movies/MovieResource.cs
@@ -5,6 +5,7 @@ using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Languages;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Movies;
+using NzbDrone.Core.Movies.Collections;
using NzbDrone.Core.Movies.Translations;
using NzbDrone.Core.Parser;
using Radarr.Api.V3.MovieFiles;
@@ -140,7 +141,7 @@ namespace Radarr.Api.V3.Movies
MovieFile = movieFile,
YouTubeTrailerId = model.MovieMetadata.Value.YouTubeTrailerId,
Studio = model.MovieMetadata.Value.Studio,
- Collection = model.MovieMetadata.Value.Collection,
+ Collection = new MovieCollection { Title = model.MovieMetadata.Value.CollectionTitle, TmdbId = model.MovieMetadata.Value.CollectionTmdbId },
Popularity = model.MovieMetadata.Value.Popularity
};
}
diff --git a/yarn.lock b/yarn.lock
index 61d674c90..2830d5eff 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -16,12 +16,7 @@
dependencies:
"@babel/highlight" "^7.16.7"
-"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4", "@babel/compat-data@^7.17.0":
- version "7.17.0"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.0.tgz#86850b8597ea6962089770952075dcaabb8dba34"
- integrity sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==
-
-"@babel/compat-data@^7.16.8", "@babel/compat-data@^7.17.7":
+"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.8", "@babel/compat-data@^7.17.0", "@babel/compat-data@^7.17.7":
version "7.17.7"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2"
integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==
@@ -56,19 +51,10 @@
eslint-visitor-keys "^2.1.0"
semver "^6.3.0"
-"@babel/generator@^7.17.3":
- version "7.17.3"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.3.tgz#a2c30b0c4f89858cb87050c3ffdfd36bdf443200"
- integrity sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==
- dependencies:
- "@babel/types" "^7.17.0"
- jsesc "^2.5.1"
- source-map "^0.5.0"
-
-"@babel/generator@^7.17.7":
- version "7.17.7"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.7.tgz#8da2599beb4a86194a3b24df6c085931d9ee45ad"
- integrity sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==
+"@babel/generator@^7.17.7", "@babel/generator@^7.17.9":
+ version "7.17.9"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.9.tgz#f4af9fd38fa8de143c29fce3f71852406fc1e2fc"
+ integrity sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ==
dependencies:
"@babel/types" "^7.17.0"
jsesc "^2.5.1"
@@ -89,17 +75,7 @@
"@babel/helper-explode-assignable-expression" "^7.16.7"
"@babel/types" "^7.16.7"
-"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b"
- integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==
- dependencies:
- "@babel/compat-data" "^7.16.4"
- "@babel/helper-validator-option" "^7.16.7"
- browserslist "^4.17.5"
- semver "^6.3.0"
-
-"@babel/helper-compilation-targets@^7.17.7":
+"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7", "@babel/helper-compilation-targets@^7.17.7":
version "7.17.7"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46"
integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==
@@ -110,14 +86,14 @@
semver "^6.3.0"
"@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7", "@babel/helper-create-class-features-plugin@^7.17.6":
- version "7.17.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz#3778c1ed09a7f3e65e6d6e0f6fbfcc53809d92c9"
- integrity sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg==
+ version "7.17.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.9.tgz#71835d7fb9f38bd9f1378e40a4c0902fdc2ea49d"
+ integrity sha512-kUjip3gruz6AJKOq5i3nC6CoCEEF/oHH3cp6tOZhB+IyyyPyW0g1Gfsxn3mkk6S08pIA2y8GQh609v9G/5sHVQ==
dependencies:
"@babel/helper-annotate-as-pure" "^7.16.7"
"@babel/helper-environment-visitor" "^7.16.7"
- "@babel/helper-function-name" "^7.16.7"
- "@babel/helper-member-expression-to-functions" "^7.16.7"
+ "@babel/helper-function-name" "^7.17.9"
+ "@babel/helper-member-expression-to-functions" "^7.17.7"
"@babel/helper-optimise-call-expression" "^7.16.7"
"@babel/helper-replace-supers" "^7.16.7"
"@babel/helper-split-export-declaration" "^7.16.7"
@@ -158,21 +134,13 @@
dependencies:
"@babel/types" "^7.16.7"
-"@babel/helper-function-name@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f"
- integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==
+"@babel/helper-function-name@^7.16.7", "@babel/helper-function-name@^7.17.9":
+ version "7.17.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12"
+ integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==
dependencies:
- "@babel/helper-get-function-arity" "^7.16.7"
"@babel/template" "^7.16.7"
- "@babel/types" "^7.16.7"
-
-"@babel/helper-get-function-arity@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419"
- integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==
- dependencies:
- "@babel/types" "^7.16.7"
+ "@babel/types" "^7.17.0"
"@babel/helper-hoist-variables@^7.16.7":
version "7.16.7"
@@ -181,12 +149,12 @@
dependencies:
"@babel/types" "^7.16.7"
-"@babel/helper-member-expression-to-functions@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0"
- integrity sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==
+"@babel/helper-member-expression-to-functions@^7.16.7", "@babel/helper-member-expression-to-functions@^7.17.7":
+ version "7.17.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.17.7.tgz#a34013b57d8542a8c4ff8ba3f747c02452a4d8c4"
+ integrity sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw==
dependencies:
- "@babel/types" "^7.16.7"
+ "@babel/types" "^7.17.0"
"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7":
version "7.16.7"
@@ -195,21 +163,7 @@
dependencies:
"@babel/types" "^7.16.7"
-"@babel/helper-module-transforms@^7.16.7":
- version "7.17.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.6.tgz#3c3b03cc6617e33d68ef5a27a67419ac5199ccd0"
- integrity sha512-2ULmRdqoOMpdvkbT8jONrZML/XALfzxlb052bldftkicAUy8AxSCkD5trDPQcwHNmolcl7wP6ehNqMlyUw6AaA==
- dependencies:
- "@babel/helper-environment-visitor" "^7.16.7"
- "@babel/helper-module-imports" "^7.16.7"
- "@babel/helper-simple-access" "^7.16.7"
- "@babel/helper-split-export-declaration" "^7.16.7"
- "@babel/helper-validator-identifier" "^7.16.7"
- "@babel/template" "^7.16.7"
- "@babel/traverse" "^7.17.3"
- "@babel/types" "^7.17.0"
-
-"@babel/helper-module-transforms@^7.17.7":
+"@babel/helper-module-transforms@^7.16.7", "@babel/helper-module-transforms@^7.17.7":
version "7.17.7"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd"
integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==
@@ -255,13 +209,6 @@
"@babel/traverse" "^7.16.7"
"@babel/types" "^7.16.7"
-"@babel/helper-simple-access@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7"
- integrity sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==
- dependencies:
- "@babel/types" "^7.16.7"
-
"@babel/helper-simple-access@^7.17.7":
version "7.17.7"
resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz#aaa473de92b7987c6dfa7ce9a7d9674724823367"
@@ -304,32 +251,27 @@
"@babel/types" "^7.16.8"
"@babel/helpers@^7.17.8":
- version "7.17.8"
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.8.tgz#288450be8c6ac7e4e44df37bcc53d345e07bc106"
- integrity sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw==
+ version "7.17.9"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.9.tgz#b2af120821bfbe44f9907b1826e168e819375a1a"
+ integrity sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==
dependencies:
"@babel/template" "^7.16.7"
- "@babel/traverse" "^7.17.3"
+ "@babel/traverse" "^7.17.9"
"@babel/types" "^7.17.0"
"@babel/highlight@^7.16.7":
- version "7.16.10"
- resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88"
- integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==
+ version "7.17.9"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.9.tgz#61b2ee7f32ea0454612def4fccdae0de232b73e3"
+ integrity sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==
dependencies:
"@babel/helper-validator-identifier" "^7.16.7"
chalk "^2.0.0"
js-tokens "^4.0.0"
-"@babel/parser@^7.16.7", "@babel/parser@^7.17.3":
- version "7.17.3"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.3.tgz#b07702b982990bf6fdc1da5049a23fece4c5c3d0"
- integrity sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==
-
-"@babel/parser@^7.17.8":
- version "7.17.8"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.8.tgz#2817fb9d885dd8132ea0f8eb615a6388cca1c240"
- integrity sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==
+"@babel/parser@^7.16.7", "@babel/parser@^7.17.8", "@babel/parser@^7.17.9":
+ version "7.17.9"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.9.tgz#9c94189a6062f0291418ca021077983058e171ef"
+ integrity sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg==
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7":
version "7.16.7"
@@ -765,9 +707,9 @@
babel-plugin-dynamic-import-node "^2.3.3"
"@babel/plugin-transform-modules-commonjs@^7.16.8":
- version "7.17.7"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.7.tgz#d86b217c8e45bb5f2dbc11eefc8eab62cf980d19"
- integrity sha512-ITPmR2V7MqioMJyrxUo2onHNC3e+MvfFiFIR0RP21d3PtlVb6sfzoxNKiphSZUOM9hEIdzCcZe83ieX3yoqjUA==
+ version "7.17.9"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.9.tgz#274be1a2087beec0254d4abd4d86e52442e1e5b6"
+ integrity sha512-2TBFd/r2I6VlYn0YRTz2JdazS+FoUuQ2rIFHoAxtyP/0G3D82SBLaRq9rnUkpqlLg03Byfl/+M32mpxjO6KaPw==
dependencies:
"@babel/helper-module-transforms" "^7.17.7"
"@babel/helper-plugin-utils" "^7.16.7"
@@ -863,11 +805,11 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/plugin-transform-regenerator@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz#9e7576dc476cb89ccc5096fff7af659243b4adeb"
- integrity sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==
+ version "7.17.9"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.17.9.tgz#0a33c3a61cf47f45ed3232903683a0afd2d3460c"
+ integrity sha512-Lc2TfbxR1HOyn/c6b4Y/b6NHoTb67n/IoWLxTu4kC7h4KQnWlhCq2S8Tx0t2SVvv5Uu87Hs+6JEJ5kt2tYGylQ==
dependencies:
- regenerator-transform "^0.14.2"
+ regenerator-transform "^0.15.0"
"@babel/plugin-transform-reserved-words@^7.16.7":
version "7.16.7"
@@ -1031,9 +973,9 @@
"@babel/plugin-transform-react-pure-annotations" "^7.16.7"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
- version "7.17.2"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941"
- integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==
+ version "7.17.9"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72"
+ integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==
dependencies:
regenerator-runtime "^0.13.4"
@@ -1046,18 +988,18 @@
"@babel/parser" "^7.16.7"
"@babel/types" "^7.16.7"
-"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.3":
- version "7.17.3"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57"
- integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==
+"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9":
+ version "7.17.9"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.9.tgz#1f9b207435d9ae4a8ed6998b2b82300d83c37a0d"
+ integrity sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw==
dependencies:
"@babel/code-frame" "^7.16.7"
- "@babel/generator" "^7.17.3"
+ "@babel/generator" "^7.17.9"
"@babel/helper-environment-visitor" "^7.16.7"
- "@babel/helper-function-name" "^7.16.7"
+ "@babel/helper-function-name" "^7.17.9"
"@babel/helper-hoist-variables" "^7.16.7"
"@babel/helper-split-export-declaration" "^7.16.7"
- "@babel/parser" "^7.17.3"
+ "@babel/parser" "^7.17.9"
"@babel/types" "^7.17.0"
debug "^4.1.0"
globals "^11.1.0"
@@ -1079,14 +1021,14 @@
minimist "^1.2.0"
"@discoveryjs/json-ext@^0.5.0":
- version "0.5.6"
- resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f"
- integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA==
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
+ integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
"@eslint/eslintrc@^1.2.1":
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6"
- integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.2.tgz#4989b9e8c0216747ee7cca314ae73791bb281aae"
+ integrity sha512-lTVWHs7O2hjBFZunXTZYnYqtB9GakA1lnxIf+gKq2nY5gxkkNi/lQvveW6t8gFdOHTg6nG50Xs95PrLqVpcaLg==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
@@ -1151,9 +1093,9 @@
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
"@jridgewell/resolve-uri@^3.0.3":
- version "3.0.5"
- resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c"
- integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==
+ version "3.0.6"
+ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.6.tgz#4ac237f4dabc8dd93330386907b97591801f7352"
+ integrity sha512-R7xHtBSNm+9SyvpJkdQl+qrM3Hm2fea3Ef197M3mUug+v+yR+Rhfbs7PBtcBUVnIWJ4JcAdjvij+c8hXS9p5aw==
"@jridgewell/sourcemap-codec@^1.4.10":
version "1.4.11"
@@ -1161,9 +1103,9 @@
integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==
"@jridgewell/trace-mapping@^0.3.0":
- version "0.3.4"
- resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3"
- integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==
+ version "0.3.9"
+ resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
+ integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
dependencies:
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
@@ -1214,9 +1156,9 @@
fastq "^1.6.0"
"@react-dnd/asap@^4.0.0":
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/@react-dnd/asap/-/asap-4.0.0.tgz#b300eeed83e9801f51bd66b0337c9a6f04548651"
- integrity sha512-0XhqJSc6pPoNnf8DhdsPHtUhRzZALVzYMTzRwV4VI6DJNJ/5xxfL9OQUwb8IH5/2x7lSf7nAZrnzUD+16VyOVQ==
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/@react-dnd/asap/-/asap-4.0.1.tgz#5291850a6b58ce6f2da25352a64f1b0674871aab"
+ integrity sha512-kLy0PJDDwvwwTXxqTFNAAllPHD73AycE9ypWeln/IguoGBEbvFcPDbCV03G52bEcC5E+YgupBE0VzHGdC8SIXg==
"@react-dnd/invariant@^2.0.0":
version "2.0.0"
@@ -1354,9 +1296,9 @@
integrity sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==
"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
- version "7.0.9"
- resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
- integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
+ version "7.0.11"
+ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
+ integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
"@types/json5@^0.0.29":
version "0.0.29"
@@ -1364,9 +1306,9 @@
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
"@types/lodash@^4.14.159":
- version "4.14.179"
- resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.179.tgz#490ec3288088c91295780237d2497a3aa9dfb5c5"
- integrity sha512-uwc1x90yCKqGcIOAT6DwOSuxnrAbpkdPsUOZtwrXb4D/6wZs+6qG7QnIawDuZWg0sWpxl+ltIKCaLoMlna678w==
+ version "4.14.182"
+ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2"
+ integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==
"@types/minimatch@*":
version "3.0.5"
@@ -1379,14 +1321,14 @@
integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==
"@types/node@*":
- version "17.0.21"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.21.tgz#864b987c0c68d07b4345845c3e63b75edd143644"
- integrity sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==
+ version "17.0.25"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.25.tgz#527051f3c2f77aa52e5dc74e45a3da5fb2301448"
+ integrity sha512-wANk6fBrUwdpY4isjWrKTufkrXdu1D2YHCot2fD/DfWxF5sMrVSA+KN7ydckvaTCh0HiqX9IVl0L5/ZoXg5M7w==
"@types/node@^12.12.54":
- version "12.20.46"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.46.tgz#7e49dee4c54fd19584e6a9e0da5f3dc2e9136bc7"
- integrity sha512-cPjLXj8d6anFPzFvOPxS3fvly3Shm5nTfl6g8X5smexixbuGUf7hfr21J5tX9JW+UPStp/5P5R8qrKL5IyVJ+A==
+ version "12.20.48"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.48.tgz#55f70bd432b6515828c0298689776861b90ca4fa"
+ integrity sha512-4kxzqkrpwYtn6okJUcb2lfUu9ilnb3yhUOH6qX3nug8D2DupZ2drIkff2yJzYcNJVl3begnlcaBJ7tqiTTzjnQ==
"@types/normalize-package-data@^2.4.0":
version "2.4.1"
@@ -1399,9 +1341,9 @@
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
"@types/prop-types@*":
- version "15.7.4"
- resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
- integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
+ version "15.7.5"
+ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
+ integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
"@types/qs@*":
version "6.9.7"
@@ -1414,9 +1356,9 @@
integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
"@types/react-redux@^7.1.16":
- version "7.1.23"
- resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.23.tgz#3c2bb1bcc698ae69d70735f33c5a8e95f41ac528"
- integrity sha512-D02o3FPfqQlfu2WeEYwh3x2otYd2Dk1o8wAfsA0B1C2AJEFxE663Ozu7JzuWbznGgW248NaOF6wsqCGNq9d3qw==
+ version "7.1.24"
+ resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.24.tgz#6caaff1603aba17b27d20f8ad073e4c077e975c0"
+ integrity sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==
dependencies:
"@types/hoist-non-react-statics" "^3.3.0"
"@types/react" "*"
@@ -1424,9 +1366,9 @@
redux "^4.0.0"
"@types/react@*":
- version "17.0.39"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.39.tgz#d0f4cde092502a6db00a1cded6e6bf2abb7633ce"
- integrity sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==
+ version "18.0.6"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.6.tgz#30206c3830af6ce8639b91ace5868bc2d3d1d96c"
+ integrity sha512-bPqwzJRzKtfI0mVYr5R+1o9BOE8UEXefwc1LwcBtfnaAn6OoqMhLa/91VA8aeWfDPJt1kHvYKI8RHcQybZLHHA==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
@@ -1665,9 +1607,9 @@ ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5:
uri-js "^4.2.2"
ajv@^8.0.0, ajv@^8.0.1, ajv@^8.8.0:
- version "8.10.0"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d"
- integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==
+ version "8.11.0"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f"
+ integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==
dependencies:
fast-deep-equal "^3.1.1"
json-schema-traverse "^1.0.0"
@@ -1754,12 +1696,12 @@ archiver-utils@^2.1.0:
readable-stream "^2.0.0"
archiver@^5.3.0:
- version "5.3.0"
- resolved "https://registry.yarnpkg.com/archiver/-/archiver-5.3.0.tgz#dd3e097624481741df626267564f7dd8640a45ba"
- integrity sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==
+ version "5.3.1"
+ resolved "https://registry.yarnpkg.com/archiver/-/archiver-5.3.1.tgz#21e92811d6f09ecfce649fbefefe8c79e57cbbb6"
+ integrity sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==
dependencies:
archiver-utils "^2.1.0"
- async "^3.2.0"
+ async "^3.2.3"
buffer-crc32 "^0.2.1"
readable-stream "^3.6.0"
readdir-glob "^1.0.0"
@@ -1799,7 +1741,7 @@ arr-union@^3.1.0:
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
-array-includes@^3.1.3, array-includes@^3.1.4:
+array-includes@^3.1.4:
version "3.1.4"
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9"
integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==
@@ -1838,22 +1780,24 @@ array-unique@^0.3.2:
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
array.prototype.flat@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13"
- integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b"
+ integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.19.0"
+ es-abstract "^1.19.2"
+ es-shim-unscopables "^1.0.0"
array.prototype.flatmap@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446"
- integrity sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz#a7e8ed4225f4788a70cd910abcf0791e76a5534f"
+ integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==
dependencies:
- call-bind "^1.0.0"
+ call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.19.0"
+ es-abstract "^1.19.2"
+ es-shim-unscopables "^1.0.0"
arrify@^1.0.1:
version "1.0.1"
@@ -1876,13 +1820,13 @@ astral-regex@^2.0.0:
integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
async@^2.6.2:
- version "2.6.3"
- resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
- integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
+ version "2.6.4"
+ resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
+ integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
dependencies:
lodash "^4.17.14"
-async@^3.2.0:
+async@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9"
integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
@@ -2049,20 +1993,20 @@ braces@^2.3.1:
split-string "^3.0.2"
to-regex "^3.0.1"
-braces@^3.0.1:
+braces@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
dependencies:
fill-range "^7.0.1"
-browserslist@^4.14.5, browserslist@^4.16.3, browserslist@^4.17.5, browserslist@^4.19.1:
- version "4.19.3"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.3.tgz#29b7caad327ecf2859485f696f9604214bedd383"
- integrity sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==
+browserslist@^4.14.5, browserslist@^4.16.3, browserslist@^4.17.5, browserslist@^4.20.2:
+ version "4.20.2"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88"
+ integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==
dependencies:
- caniuse-lite "^1.0.30001312"
- electron-to-chromium "^1.4.71"
+ caniuse-lite "^1.0.30001317"
+ electron-to-chromium "^1.4.84"
escalade "^3.1.1"
node-releases "^2.0.2"
picocolors "^1.0.0"
@@ -2157,10 +2101,10 @@ camelcase@^5.3.1:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
-caniuse-lite@^1.0.30001196, caniuse-lite@^1.0.30001312:
- version "1.0.30001313"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001313.tgz#a380b079db91621e1b7120895874e2fd62ed2e2f"
- integrity sha512-rI1UN0koZUiKINjysQDuRi2VeSCce3bYJNmDcj3PIKREiAmjakugBul1QSkg/fPrlULYl6oWfGg3PbgOSY9X4Q==
+caniuse-lite@^1.0.30001196, caniuse-lite@^1.0.30001317:
+ version "1.0.30001332"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz#39476d3aa8d83ea76359c70302eafdd4a1d727dd"
+ integrity sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw==
capture-exit@^2.0.0:
version "2.0.0"
@@ -2217,7 +2161,7 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
-classnames@2.3.1:
+classnames@2.3.1, classnames@^2.2.5:
version "2.3.1"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
@@ -2415,11 +2359,11 @@ copy-descriptor@^0.1.0:
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
core-js-compat@^3.20.2, core-js-compat@^3.21.0:
- version "3.21.1"
- resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.21.1.tgz#cac369f67c8d134ff8f9bd1623e3bc2c42068c82"
- integrity sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g==
+ version "3.22.2"
+ resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.2.tgz#eec621eb276518efcf718d0a6d9d042c3d0cad48"
+ integrity sha512-Fns9lU06ZJ07pdfmPMu7OnkIKGPKDzXKIiuGlSvHHapwqMUF2QnnsWwtueFZtSyZEilP0o6iUeHQwpn7LxtLUw==
dependencies:
- browserslist "^4.19.1"
+ browserslist "^4.20.2"
semver "7.0.0"
core-js@3.12.1:
@@ -2474,12 +2418,9 @@ cpy@^8.1.2:
p-map "^3.0.0"
crc-32@^1.2.0:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.1.tgz#436d2bcaad27bcb6bd073a2587139d3024a16460"
- integrity sha512-Dn/xm/1vFFgs3nfrpEVScHoIslO9NZRITWGz/1E/St6u4xw99vfZzVkW0OSnzx2h9egej9xwMCEut6sqwokM/w==
- dependencies:
- exit-on-epipe "~1.0.1"
- printj "~1.3.1"
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff"
+ integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==
crc32-stream@^4.0.2:
version "4.0.2"
@@ -2536,20 +2477,20 @@ css-loader@6.5.1:
semver "^7.3.5"
css-select@^4.1.3:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd"
- integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b"
+ integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==
dependencies:
boolbase "^1.0.0"
- css-what "^5.1.0"
- domhandler "^4.3.0"
+ css-what "^6.0.1"
+ domhandler "^4.3.1"
domutils "^2.8.0"
nth-check "^2.0.1"
-css-what@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe"
- integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==
+css-what@^6.0.1:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
+ integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
cssesc@^3.0.0:
version "3.0.0"
@@ -2580,14 +2521,7 @@ debug@^3.1.0, debug@^3.1.1, debug@^3.2.7:
dependencies:
ms "^2.1.1"
-debug@^4.1.0, debug@^4.1.1:
- version "4.3.3"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
- integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
- dependencies:
- ms "2.1.2"
-
-debug@^4.3.2, debug@^4.3.3:
+debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -2630,11 +2564,12 @@ deep-is@^0.1.3:
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
define-properties@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
- integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1"
+ integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==
dependencies:
- object-keys "^1.0.12"
+ has-property-descriptors "^1.0.0"
+ object-keys "^1.1.1"
define-property@^0.2.5:
version "0.2.5"
@@ -2753,23 +2688,23 @@ dom-css@^2.0.0:
"@babel/runtime" "^7.1.2"
dom-serializer@^1.0.1:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91"
- integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30"
+ integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==
dependencies:
domelementtype "^2.0.1"
domhandler "^4.2.0"
entities "^2.0.0"
domelementtype@^2.0.1, domelementtype@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
- integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
+ integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
-domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626"
- integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==
+domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1:
+ version "4.3.1"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c"
+ integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==
dependencies:
domelementtype "^2.2.0"
@@ -2790,10 +2725,10 @@ dot-case@^3.0.4:
no-case "^3.0.4"
tslib "^2.0.3"
-electron-to-chromium@^1.4.71:
- version "1.4.76"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.76.tgz#a0494baedaf51094b1c172999919becd9975a934"
- integrity sha512-3Vftv7cenJtQb+k00McEBZ2vVmZ/x+HEF7pcZONZIkOsESqAqVuACmBxMv0JhzX7u0YltU0vSqRqgBSTAhFUjA==
+electron-to-chromium@^1.4.84:
+ version "1.4.118"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.118.tgz#2d917c71712dac9652cc01af46c7d0bd51552974"
+ integrity sha512-maZIKjnYDvF7Fs35nvVcyr44UcKNwybr93Oba2n3HkKDFAtk0svERkLN/HyczJDS3Fo4wU9th9fUQd09ZLtj1w==
element-class@0.2.2:
version "0.2.2"
@@ -2825,6 +2760,11 @@ enhanced-resolve@^5.8.3:
graceful-fs "^4.2.4"
tapable "^2.2.0"
+enquire.js@^2.1.6:
+ version "2.1.6"
+ resolved "https://registry.yarnpkg.com/enquire.js/-/enquire.js-2.1.6.tgz#3e8780c9b8b835084c3f60e166dbc3c2a3c89814"
+ integrity sha1-PoeAybi4NQhMP2DhZtvDwqPImBQ=
+
entities@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
@@ -2849,10 +2789,10 @@ error@^7.0.0:
dependencies:
string-template "~0.2.1"
-es-abstract@^1.19.0, es-abstract@^1.19.1:
- version "1.19.1"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3"
- integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==
+es-abstract@^1.19.1, es-abstract@^1.19.2:
+ version "1.19.5"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.5.tgz#a2cb01eb87f724e815b278b0dd0d00f36ca9a7f1"
+ integrity sha512-Aa2G2+Rd3b6kxEUKTF4TaW67czBLyAv3z7VOhYRU50YBx+bbsYZ9xQP4lMNazePuFlybXI0V4MruPos7qUo5fA==
dependencies:
call-bind "^1.0.2"
es-to-primitive "^1.2.1"
@@ -2860,15 +2800,15 @@ es-abstract@^1.19.0, es-abstract@^1.19.1:
get-intrinsic "^1.1.1"
get-symbol-description "^1.0.0"
has "^1.0.3"
- has-symbols "^1.0.2"
+ has-symbols "^1.0.3"
internal-slot "^1.0.3"
is-callable "^1.2.4"
- is-negative-zero "^2.0.1"
+ is-negative-zero "^2.0.2"
is-regex "^1.1.4"
- is-shared-array-buffer "^1.0.1"
+ is-shared-array-buffer "^1.0.2"
is-string "^1.0.7"
- is-weakref "^1.0.1"
- object-inspect "^1.11.0"
+ is-weakref "^1.0.2"
+ object-inspect "^1.12.0"
object-keys "^1.1.1"
object.assign "^4.1.2"
string.prototype.trimend "^1.0.4"
@@ -2880,6 +2820,13 @@ es-module-lexer@^0.9.0:
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19"
integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==
+es-shim-unscopables@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241"
+ integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==
+ dependencies:
+ has "^1.0.3"
+
es-to-primitive@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
@@ -3177,11 +3124,6 @@ execall@^2.0.0:
dependencies:
clone-regexp "^2.1.0"
-exit-on-epipe@~1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692"
- integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==
-
expand-brackets@^2.1.4:
version "2.1.4"
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
@@ -3416,9 +3358,9 @@ for-in@^1.0.2:
integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=
fraction.js@^4.0.13:
- version "4.1.3"
- resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.3.tgz#be65b0f20762ef27e1e793860bc2dfb716e99e65"
- integrity sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg==
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950"
+ integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==
fragment-cache@^0.2.1:
version "0.2.1"
@@ -3433,9 +3375,9 @@ fs-constants@^1.0.0:
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
fs-extra@^10.0.0:
- version "10.0.1"
- resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.1.tgz#27de43b4320e833f6867cc044bfce29fdf0ef3b8"
- integrity sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==
+ version "10.1.0"
+ resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
+ integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
@@ -3456,6 +3398,11 @@ functional-red-black-tree@^1.0.1:
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
+functions-have-names@^1.2.2:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
+ integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
+
fuse.js@6.4.6:
version "6.4.6"
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-6.4.6.tgz#62f216c110e5aa22486aff20be7896d19a059b79"
@@ -3581,9 +3528,9 @@ globals@^11.1.0:
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
globals@^13.6.0, globals@^13.9.0:
- version "13.12.1"
- resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.1.tgz#ec206be932e6c77236677127577aa8e50bf1c5cb"
- integrity sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==
+ version "13.13.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-13.13.0.tgz#ac32261060d8070e2719dd6998406e27d2b5727b"
+ integrity sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==
dependencies:
type-fest "^0.20.2"
@@ -3626,9 +3573,9 @@ good-listener@^1.2.2:
delegate "^3.1.2"
graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4:
- version "4.2.9"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96"
- integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
+ version "4.2.10"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
+ integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
gud@^1.0.0:
version "1.0.0"
@@ -3648,9 +3595,9 @@ has-ansi@^2.0.0:
ansi-regex "^2.0.0"
has-bigints@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113"
- integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
+ integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==
has-flag@^3.0.0:
version "3.0.0"
@@ -3669,6 +3616,13 @@ has-glob@^1.0.0:
dependencies:
is-glob "^3.0.0"
+has-property-descriptors@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861"
+ integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==
+ dependencies:
+ get-intrinsic "^1.1.1"
+
has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
@@ -3769,9 +3723,9 @@ html-minifier-terser@^5.0.1:
terser "^4.6.3"
html-tags@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140"
- integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.2.0.tgz#dbb3518d20b726524e4dd43de397eb0a95726961"
+ integrity sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==
html-webpack-plugin@5.3.1:
version "5.3.1"
@@ -3795,9 +3749,9 @@ htmlparser2@^6.1.0:
entities "^2.0.0"
http-parser-js@>=0.5.1:
- version "0.5.5"
- resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5"
- integrity sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==
+ version "0.5.6"
+ resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.6.tgz#2e02406ab2df8af8a7abfba62e0da01c62b95afd"
+ integrity sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA==
https-browserify@1.0.0:
version "1.0.0"
@@ -3967,9 +3921,9 @@ is-callable@^1.1.4, is-callable@^1.2.4:
integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
is-core-module@^2.2.0, is-core-module@^2.5.0, is-core-module@^2.8.0, is-core-module@^2.8.1:
- version "2.8.1"
- resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211"
- integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==
+ version "2.9.0"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69"
+ integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==
dependencies:
has "^1.0.3"
@@ -4048,15 +4002,15 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3:
dependencies:
is-extglob "^2.1.1"
-is-negative-zero@^2.0.1:
+is-negative-zero@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150"
integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==
is-number-object@^1.0.4:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0"
- integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc"
+ integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==
dependencies:
has-tostringtag "^1.0.0"
@@ -4112,10 +4066,12 @@ is-regexp@^2.0.0:
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-2.1.0.tgz#cd734a56864e23b956bf4e7c66c396a4c0b22c2d"
integrity sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==
-is-shared-array-buffer@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6"
- integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==
+is-shared-array-buffer@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79"
+ integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==
+ dependencies:
+ call-bind "^1.0.2"
is-stream@^2.0.0:
version "2.0.1"
@@ -4136,7 +4092,7 @@ is-symbol@^1.0.2, is-symbol@^1.0.3:
dependencies:
has-symbols "^1.0.2"
-is-weakref@^1.0.1:
+is-weakref@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"
integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==
@@ -4277,6 +4233,13 @@ json-stringify-safe@^5.0.1:
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
+json2mq@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/json2mq/-/json2mq-0.2.0.tgz#b637bd3ba9eabe122c83e9720483aeb10d2c904a"
+ integrity sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=
+ dependencies:
+ string-convert "^0.2.0"
+
json5@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
@@ -4285,11 +4248,9 @@ json5@^1.0.1:
minimist "^1.2.0"
json5@^2.1.2:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
- integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
- dependencies:
- minimist "^1.2.5"
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
+ integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
jsonc-parser@^3.0.0:
version "3.0.0"
@@ -4311,11 +4272,11 @@ jsonparse@^1.2.0:
integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=
"jsx-ast-utils@^2.4.1 || ^3.0.0":
- version "3.2.1"
- resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz#720b97bfe7d901b927d87c3773637ae8ea48781b"
- integrity sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.2.tgz#6ab1e52c71dfc0c0707008a91729a9491fe9f76c"
+ integrity sha512-HDAyJ4MNQBboGpUnHAVUNJs6X0lh058s6FuixsFGP7MgJYpD6Vasd6nzSG5iIfXu1zAYlHJ/zsOKNlrenTUBnw==
dependencies:
- array-includes "^3.1.3"
+ array-includes "^3.1.4"
object.assign "^4.1.2"
junk@^3.1.0:
@@ -4405,9 +4366,9 @@ livereload-js@^2.3.0:
integrity sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==
loader-runner@^4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
- integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1"
+ integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
loader-utils@^1.4.0:
version "1.4.0"
@@ -4629,24 +4590,24 @@ micromatch@^3.1.10:
to-regex "^3.0.2"
micromatch@^4.0.2, micromatch@^4.0.4:
- version "4.0.4"
- resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
- integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
+ integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
dependencies:
- braces "^3.0.1"
- picomatch "^2.2.3"
+ braces "^3.0.2"
+ picomatch "^2.3.1"
-mime-db@1.51.0:
- version "1.51.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c"
- integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==
+mime-db@1.52.0:
+ version "1.52.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
+ integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.27:
- version "2.1.34"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24"
- integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==
+ version "2.1.35"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
+ integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
- mime-db "1.51.0"
+ mime-db "1.52.0"
mime@~2.5.2:
version "2.5.2"
@@ -4703,10 +4664,10 @@ minimist-options@4.1.0:
is-plain-obj "^1.1.0"
kind-of "^6.0.3"
-minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
- integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.6:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
+ integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
mixin-deep@^1.2.0:
version "1.3.2"
@@ -4717,11 +4678,11 @@ mixin-deep@^1.2.0:
is-extendable "^1.0.1"
mkdirp@^0.5.5:
- version "0.5.5"
- resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
- integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
+ version "0.5.6"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
+ integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
dependencies:
- minimist "^1.2.5"
+ minimist "^1.2.6"
mobile-detect@1.4.5:
version "1.4.5"
@@ -4754,9 +4715,9 @@ ms@^2.1.1:
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
nanoid@^3.1.22, nanoid@^3.3.1:
- version "3.3.1"
- resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35"
- integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25"
+ integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==
nanomatch@^1.2.9:
version "1.2.13"
@@ -4786,9 +4747,9 @@ neo-async@^2.6.2:
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61"
- integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz#26c8a3cee6cc05fbcf1e333cd2fc3e003326c0b5"
+ integrity sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==
no-case@^3.0.4:
version "3.0.4"
@@ -4811,9 +4772,9 @@ node-int64@^0.4.0:
integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=
node-releases@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01"
- integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96"
+ integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw==
normalize-package-data@^2.5.0:
version "2.5.0"
@@ -4888,7 +4849,7 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
-object-inspect@^1.11.0, object-inspect@^1.9.0:
+object-inspect@^1.12.0, object-inspect@^1.9.0:
version "1.12.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0"
integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==
@@ -4901,7 +4862,7 @@ object-is@^1.0.1:
call-bind "^1.0.2"
define-properties "^1.1.3"
-object-keys@^1.0.12, object-keys@^1.1.1:
+object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
@@ -5190,7 +5151,7 @@ picocolors@^1.0.0:
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
-picomatch@^2.0.4, picomatch@^2.2.3:
+picomatch@^2.0.4, picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
@@ -5334,15 +5295,7 @@ postcss-safe-parser@^6.0.0:
resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz#bb4c29894171a94bc5c996b9a30317ef402adaa1"
integrity sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==
-postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.9:
- version "6.0.9"
- resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f"
- integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==
- dependencies:
- cssesc "^3.0.0"
- util-deprecate "^1.0.2"
-
-postcss-selector-parser@^6.0.6:
+postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.6, postcss-selector-parser@^6.0.9:
version "6.0.10"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d"
integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==
@@ -5398,16 +5351,7 @@ postcss@^6.0.23:
source-map "^0.6.1"
supports-color "^5.4.0"
-postcss@^8.1.6:
- version "8.4.7"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.7.tgz#f99862069ec4541de386bf57f5660a6c7a0875a8"
- integrity sha512-L9Ye3r6hkkCeOETQX6iOaWZgjp3LL6Lpqm6EtgbKrgqGGteRMNb9vzBfRL96YOSu8o7x3MfIH9Mo5cPJFGrW6A==
- dependencies:
- nanoid "^3.3.1"
- picocolors "^1.0.0"
- source-map-js "^1.0.2"
-
-postcss@^8.2.15, postcss@^8.3.11, postcss@^8.4.12:
+postcss@^8.1.6, postcss@^8.2.15, postcss@^8.3.11, postcss@^8.4.12:
version "8.4.12"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905"
integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==
@@ -5434,11 +5378,6 @@ pretty-error@^2.1.1:
lodash "^4.17.20"
renderkid "^2.0.4"
-printj@~1.3.1:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/printj/-/printj-1.3.1.tgz#9af6b1d55647a1587ac44f4c1654a4b95b8e12cb"
- integrity sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==
-
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -5730,6 +5669,17 @@ react-side-effect@^1.0.2:
dependencies:
shallowequal "^1.0.1"
+react-slick@0.28.1:
+ version "0.28.1"
+ resolved "https://registry.yarnpkg.com/react-slick/-/react-slick-0.28.1.tgz#12c18d991b59432df9c3757ba540a227b3fb85b9"
+ integrity sha512-JwRQXoWGJRbUTE7eZI1rGIHaXX/4YuwX6gn7ulfvUZ4vFDVQAA25HcsHSYaUiRCduTr6rskyIuyPMpuG6bbluw==
+ dependencies:
+ classnames "^2.2.5"
+ enquire.js "^2.1.6"
+ json2mq "^0.2.0"
+ lodash.debounce "^4.0.8"
+ resize-observer-polyfill "^1.5.0"
+
react-slider@1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/react-slider/-/react-slider-1.1.4.tgz#08b55f9be3e04cc10ae00cc3aedb6891dffe9bf3"
@@ -5880,9 +5830,9 @@ redux@4.1.0:
"@babel/runtime" "^7.9.2"
redux@^4.0.0, redux@^4.0.5:
- version "4.1.2"
- resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104"
- integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.0.tgz#46f10d6e29b6666df758780437651eeb2b969f13"
+ integrity sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==
dependencies:
"@babel/runtime" "^7.9.2"
@@ -5908,10 +5858,10 @@ regenerator-runtime@^0.13.4:
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
-regenerator-transform@^0.14.2:
- version "0.14.5"
- resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4"
- integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==
+regenerator-transform@^0.15.0:
+ version "0.15.0"
+ resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537"
+ integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==
dependencies:
"@babel/runtime" "^7.8.4"
@@ -5924,12 +5874,13 @@ regex-not@^1.0.0, regex-not@^1.0.2:
safe-regex "^1.1.0"
regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.1:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307"
- integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==
+ version "1.4.3"
+ resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"
+ integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
+ functions-have-names "^1.2.2"
regexpp@^3.2.0:
version "3.2.0"
@@ -6011,7 +5962,7 @@ reselect@4.0.0:
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7"
integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==
-resize-observer-polyfill@^1.4.1:
+resize-observer-polyfill@^1.4.1, resize-observer-polyfill@^1.5.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
@@ -6207,9 +6158,9 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.3.4, semver@^7.3.5:
- version "7.3.5"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
- integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
+ version "7.3.7"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
+ integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
dependencies:
lru-cache "^6.0.0"
@@ -6292,6 +6243,11 @@ slice-ansi@^4.0.0:
astral-regex "^2.0.0"
is-fullwidth-code-point "^3.0.0"
+slick-carousel@1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/slick-carousel/-/slick-carousel-1.8.1.tgz#a4bfb29014887bb66ce528b90bd0cda262cc8f8d"
+ integrity sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==
+
snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
@@ -6425,6 +6381,11 @@ streamqueue@1.1.2:
isstream "^0.1.2"
readable-stream "^2.3.3"
+string-convert@^0.2.0:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97"
+ integrity sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=
+
string-template@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add"
@@ -6688,9 +6649,9 @@ terser@^4.6.3:
source-map-support "~0.5.12"
terser@^5.7.2:
- version "5.12.0"
- resolved "https://registry.yarnpkg.com/terser/-/terser-5.12.0.tgz#728c6bff05f7d1dcb687d8eace0644802a9dae8a"
- integrity sha512-R3AUhNBGWiFc77HXag+1fXpAxTAFRQTJemlJKjAgD9r8xXTpjNKqIXwHM/o7Rh+O0kUJtS3WQVdBeMKFk5sw9A==
+ version "5.12.1"
+ resolved "https://registry.yarnpkg.com/terser/-/terser-5.12.1.tgz#4cf2ebed1f5bceef5c83b9f60104ac4a78b49e9c"
+ integrity sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==
dependencies:
acorn "^8.5.0"
commander "^2.20.0"
@@ -6820,13 +6781,13 @@ trim-newlines@^3.0.0:
integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==
tsconfig-paths@^3.12.0:
- version "3.14.0"
- resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.0.tgz#4fcc48f9ccea8826c41b9ca093479de7f5018976"
- integrity sha512-cg/1jAZoL57R39+wiw4u/SCC6Ic9Q5NqjBOb+9xISedOYurfog9ZNmKJSxAnb2m/5Bq4lE9lhUcau33Ml8DM0g==
+ version "3.14.1"
+ resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a"
+ integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==
dependencies:
"@types/json5" "^0.0.29"
json5 "^1.0.1"
- minimist "^1.2.0"
+ minimist "^1.2.6"
strip-bom "^3.0.0"
tslib@^1.9.3:
@@ -6834,10 +6795,10 @@ tslib@^1.9.3:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
-tslib@^2.0.3:
- version "2.3.1"
- resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
- integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
+tslib@^2.0.0, tslib@^2.0.3:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
+ integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
@@ -6962,17 +6923,19 @@ url-parse@^1.4.3:
requires-port "^1.0.0"
use-callback-ref@^1.2.1:
- version "1.2.5"
- resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.2.5.tgz#6115ed242cfbaed5915499c0a9842ca2912f38a5"
- integrity sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.0.tgz#772199899b9c9a50526fedc4993fc7fa1f7e32d5"
+ integrity sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==
+ dependencies:
+ tslib "^2.0.0"
use-sidecar@^1.0.1:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.0.5.tgz#ffff2a17c1df42e348624b699ba6e5c220527f2b"
- integrity sha512-k9jnrjYNwN6xYLj1iaGhonDghfvmeTmYjAiGvOr7clwKfPjMXJf4/HOr7oT5tJwYafgp2tG2l3eZEOfoELiMcA==
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2"
+ integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==
dependencies:
detect-node-es "^1.1.0"
- tslib "^1.9.3"
+ tslib "^2.0.0"
use@^3.1.0:
version "3.1.1"
@@ -7274,9 +7237,9 @@ yargs-parser@^21.0.0:
integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==
yargs@^17.3.1:
- version "17.4.0"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.4.0.tgz#9fc9efc96bd3aa2c1240446af28499f0e7593d00"
- integrity sha512-WJudfrk81yWFSOkZYpAZx4Nt7V4xp7S/uJkX0CnxovMCt1wCE8LNftPpNuF9X/u9gN5nsD7ycYtRcDf2pL3UiA==
+ version "17.4.1"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.4.1.tgz#ebe23284207bb75cee7c408c33e722bfb27b5284"
+ integrity sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g==
dependencies:
cliui "^7.0.2"
escalade "^3.1.1"