mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
Show Indexer Status on Indexer Table
This commit is contained in:
@@ -6,6 +6,7 @@ import { createSelector } from 'reselect';
|
|||||||
import { saveDimensions, setIsSidebarVisible } from 'Store/Actions/appActions';
|
import { saveDimensions, setIsSidebarVisible } from 'Store/Actions/appActions';
|
||||||
import { fetchCustomFilters } from 'Store/Actions/customFilterActions';
|
import { fetchCustomFilters } from 'Store/Actions/customFilterActions';
|
||||||
import { fetchIndexers } from 'Store/Actions/indexerActions';
|
import { fetchIndexers } from 'Store/Actions/indexerActions';
|
||||||
|
import { fetchIndexerStatus } from 'Store/Actions/indexerStatusActions';
|
||||||
import { fetchIndexerCategories, fetchIndexerFlags, fetchLanguages, fetchUISettings } from 'Store/Actions/settingsActions';
|
import { fetchIndexerCategories, fetchIndexerFlags, fetchLanguages, fetchUISettings } from 'Store/Actions/settingsActions';
|
||||||
import { fetchStatus } from 'Store/Actions/systemActions';
|
import { fetchStatus } from 'Store/Actions/systemActions';
|
||||||
import { fetchTags } from 'Store/Actions/tagActions';
|
import { fetchTags } from 'Store/Actions/tagActions';
|
||||||
@@ -48,6 +49,7 @@ const selectIsPopulated = createSelector(
|
|||||||
(state) => state.settings.ui.isPopulated,
|
(state) => state.settings.ui.isPopulated,
|
||||||
(state) => state.settings.languages.isPopulated,
|
(state) => state.settings.languages.isPopulated,
|
||||||
(state) => state.indexers.isPopulated,
|
(state) => state.indexers.isPopulated,
|
||||||
|
(state) => state.indexerStatus.isPopulated,
|
||||||
(state) => state.settings.indexerCategories.isPopulated,
|
(state) => state.settings.indexerCategories.isPopulated,
|
||||||
(state) => state.settings.indexerFlags.isPopulated,
|
(state) => state.settings.indexerFlags.isPopulated,
|
||||||
(state) => state.system.status.isPopulated,
|
(state) => state.system.status.isPopulated,
|
||||||
@@ -57,6 +59,7 @@ const selectIsPopulated = createSelector(
|
|||||||
uiSettingsIsPopulated,
|
uiSettingsIsPopulated,
|
||||||
languagesIsPopulated,
|
languagesIsPopulated,
|
||||||
indexersIsPopulated,
|
indexersIsPopulated,
|
||||||
|
indexerStatusIsPopulated,
|
||||||
indexerCategoriesIsPopulated,
|
indexerCategoriesIsPopulated,
|
||||||
indexerFlagsIsPopulated,
|
indexerFlagsIsPopulated,
|
||||||
systemStatusIsPopulated
|
systemStatusIsPopulated
|
||||||
@@ -67,6 +70,7 @@ const selectIsPopulated = createSelector(
|
|||||||
uiSettingsIsPopulated &&
|
uiSettingsIsPopulated &&
|
||||||
languagesIsPopulated &&
|
languagesIsPopulated &&
|
||||||
indexersIsPopulated &&
|
indexersIsPopulated &&
|
||||||
|
indexerStatusIsPopulated &&
|
||||||
indexerCategoriesIsPopulated &&
|
indexerCategoriesIsPopulated &&
|
||||||
indexerFlagsIsPopulated &&
|
indexerFlagsIsPopulated &&
|
||||||
systemStatusIsPopulated
|
systemStatusIsPopulated
|
||||||
@@ -80,6 +84,7 @@ const selectErrors = createSelector(
|
|||||||
(state) => state.settings.ui.error,
|
(state) => state.settings.ui.error,
|
||||||
(state) => state.settings.languages.error,
|
(state) => state.settings.languages.error,
|
||||||
(state) => state.indexers.error,
|
(state) => state.indexers.error,
|
||||||
|
(state) => state.indexerStatus.error,
|
||||||
(state) => state.settings.indexerCategories.error,
|
(state) => state.settings.indexerCategories.error,
|
||||||
(state) => state.settings.indexerFlags.error,
|
(state) => state.settings.indexerFlags.error,
|
||||||
(state) => state.system.status.error,
|
(state) => state.system.status.error,
|
||||||
@@ -89,6 +94,7 @@ const selectErrors = createSelector(
|
|||||||
uiSettingsError,
|
uiSettingsError,
|
||||||
languagesError,
|
languagesError,
|
||||||
indexersError,
|
indexersError,
|
||||||
|
indexerStatusError,
|
||||||
indexerCategoriesError,
|
indexerCategoriesError,
|
||||||
indexerFlagsError,
|
indexerFlagsError,
|
||||||
systemStatusError
|
systemStatusError
|
||||||
@@ -99,6 +105,7 @@ const selectErrors = createSelector(
|
|||||||
uiSettingsError ||
|
uiSettingsError ||
|
||||||
languagesError ||
|
languagesError ||
|
||||||
indexersError ||
|
indexersError ||
|
||||||
|
indexerStatusError ||
|
||||||
indexerCategoriesError ||
|
indexerCategoriesError ||
|
||||||
indexerFlagsError ||
|
indexerFlagsError ||
|
||||||
systemStatusError
|
systemStatusError
|
||||||
@@ -111,6 +118,7 @@ const selectErrors = createSelector(
|
|||||||
uiSettingsError,
|
uiSettingsError,
|
||||||
languagesError,
|
languagesError,
|
||||||
indexersError,
|
indexersError,
|
||||||
|
indexerStatusError,
|
||||||
indexerCategoriesError,
|
indexerCategoriesError,
|
||||||
indexerFlagsError,
|
indexerFlagsError,
|
||||||
systemStatusError
|
systemStatusError
|
||||||
@@ -157,6 +165,9 @@ function createMapDispatchToProps(dispatch, props) {
|
|||||||
dispatchFetchIndexers() {
|
dispatchFetchIndexers() {
|
||||||
dispatch(fetchIndexers());
|
dispatch(fetchIndexers());
|
||||||
},
|
},
|
||||||
|
dispatchFetchIndexerStatus() {
|
||||||
|
dispatch(fetchIndexerStatus());
|
||||||
|
},
|
||||||
dispatchFetchIndexerCategories() {
|
dispatchFetchIndexerCategories() {
|
||||||
dispatch(fetchIndexerCategories());
|
dispatch(fetchIndexerCategories());
|
||||||
},
|
},
|
||||||
@@ -197,6 +208,7 @@ class PageConnector extends Component {
|
|||||||
this.props.dispatchFetchTags();
|
this.props.dispatchFetchTags();
|
||||||
this.props.dispatchFetchLanguages();
|
this.props.dispatchFetchLanguages();
|
||||||
this.props.dispatchFetchIndexers();
|
this.props.dispatchFetchIndexers();
|
||||||
|
this.props.dispatchFetchIndexerStatus();
|
||||||
this.props.dispatchFetchIndexerCategories();
|
this.props.dispatchFetchIndexerCategories();
|
||||||
this.props.dispatchFetchIndexerFlags();
|
this.props.dispatchFetchIndexerFlags();
|
||||||
this.props.dispatchFetchUISettings();
|
this.props.dispatchFetchUISettings();
|
||||||
@@ -221,6 +233,7 @@ class PageConnector extends Component {
|
|||||||
dispatchFetchTags,
|
dispatchFetchTags,
|
||||||
dispatchFetchLanguages,
|
dispatchFetchLanguages,
|
||||||
dispatchFetchIndexers,
|
dispatchFetchIndexers,
|
||||||
|
dispatchFetchIndexerStatus,
|
||||||
dispatchFetchIndexerCategories,
|
dispatchFetchIndexerCategories,
|
||||||
dispatchFetchIndexerFlags,
|
dispatchFetchIndexerFlags,
|
||||||
dispatchFetchUISettings,
|
dispatchFetchUISettings,
|
||||||
@@ -260,6 +273,7 @@ PageConnector.propTypes = {
|
|||||||
dispatchFetchTags: PropTypes.func.isRequired,
|
dispatchFetchTags: PropTypes.func.isRequired,
|
||||||
dispatchFetchLanguages: PropTypes.func.isRequired,
|
dispatchFetchLanguages: PropTypes.func.isRequired,
|
||||||
dispatchFetchIndexers: PropTypes.func.isRequired,
|
dispatchFetchIndexers: PropTypes.func.isRequired,
|
||||||
|
dispatchFetchIndexerStatus: PropTypes.func.isRequired,
|
||||||
dispatchFetchIndexerCategories: PropTypes.func.isRequired,
|
dispatchFetchIndexerCategories: PropTypes.func.isRequired,
|
||||||
dispatchFetchIndexerFlags: PropTypes.func.isRequired,
|
dispatchFetchIndexerFlags: PropTypes.func.isRequired,
|
||||||
dispatchFetchUISettings: PropTypes.func.isRequired,
|
dispatchFetchUISettings: PropTypes.func.isRequired,
|
||||||
|
@@ -6,6 +6,8 @@ import * as commandNames from 'Commands/commandNames';
|
|||||||
import { executeCommand } from 'Store/Actions/commandActions';
|
import { executeCommand } from 'Store/Actions/commandActions';
|
||||||
import createExecutingCommandsSelector from 'Store/Selectors/createExecutingCommandsSelector';
|
import createExecutingCommandsSelector from 'Store/Selectors/createExecutingCommandsSelector';
|
||||||
import createIndexerSelector from 'Store/Selectors/createIndexerSelector';
|
import createIndexerSelector from 'Store/Selectors/createIndexerSelector';
|
||||||
|
import createIndexerStatusSelector from 'Store/Selectors/createIndexerStatusSelector';
|
||||||
|
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
|
||||||
|
|
||||||
function selectShowSearchAction() {
|
function selectShowSearchAction() {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
@@ -19,12 +21,16 @@ function selectShowSearchAction() {
|
|||||||
function createMapStateToProps() {
|
function createMapStateToProps() {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
createIndexerSelector(),
|
createIndexerSelector(),
|
||||||
|
createIndexerStatusSelector(),
|
||||||
selectShowSearchAction(),
|
selectShowSearchAction(),
|
||||||
createExecutingCommandsSelector(),
|
createExecutingCommandsSelector(),
|
||||||
|
createUISettingsSelector(),
|
||||||
(
|
(
|
||||||
movie,
|
movie,
|
||||||
|
status,
|
||||||
showSearchAction,
|
showSearchAction,
|
||||||
executingCommands
|
executingCommands,
|
||||||
|
uiSettings
|
||||||
) => {
|
) => {
|
||||||
|
|
||||||
// If a movie is deleted this selector may fire before the parent
|
// If a movie is deleted this selector may fire before the parent
|
||||||
@@ -32,6 +38,8 @@ function createMapStateToProps() {
|
|||||||
// we want to return early here and again in the render function to avoid
|
// we want to return early here and again in the render function to avoid
|
||||||
// trying to show a movie that has no information available.
|
// trying to show a movie that has no information available.
|
||||||
|
|
||||||
|
console.log(status);
|
||||||
|
|
||||||
if (!movie) {
|
if (!movie) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -52,9 +60,12 @@ function createMapStateToProps() {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...movie,
|
...movie,
|
||||||
|
status,
|
||||||
showSearchAction,
|
showSearchAction,
|
||||||
isRefreshingMovie,
|
isRefreshingMovie,
|
||||||
isSearchingMovie
|
isSearchingMovie,
|
||||||
|
longDateFormat: uiSettings.longDateFormat,
|
||||||
|
timeFormat: uiSettings.timeFormat
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@@ -3,12 +3,16 @@ import React from 'react';
|
|||||||
import Icon from 'Components/Icon';
|
import Icon from 'Components/Icon';
|
||||||
import VirtualTableRowCell from 'Components/Table/Cells/TableRowCell';
|
import VirtualTableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import { icons, kinds } from 'Helpers/Props';
|
import { icons, kinds } from 'Helpers/Props';
|
||||||
|
import formatDateTime from 'Utilities/Date/formatDateTime';
|
||||||
import styles from './IndexerStatusCell.css';
|
import styles from './IndexerStatusCell.css';
|
||||||
|
|
||||||
function IndexerStatusCell(props) {
|
function IndexerStatusCell(props) {
|
||||||
const {
|
const {
|
||||||
className,
|
className,
|
||||||
enabled,
|
enabled,
|
||||||
|
status,
|
||||||
|
longDateFormat,
|
||||||
|
timeFormat,
|
||||||
component: Component,
|
component: Component,
|
||||||
...otherProps
|
...otherProps
|
||||||
} = props;
|
} = props;
|
||||||
@@ -26,6 +30,15 @@ function IndexerStatusCell(props) {
|
|||||||
title={enabled ? 'Indexer is Enabled' : 'Indexer is Disabled'}
|
title={enabled ? 'Indexer is Enabled' : 'Indexer is Disabled'}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
status &&
|
||||||
|
<Icon
|
||||||
|
className={styles.statusIcon}
|
||||||
|
kind={kinds.DANGER}
|
||||||
|
name={icons.WARNING}
|
||||||
|
title={`Indexer is Disabled due to failures until ${formatDateTime(status.disabledTill, longDateFormat, timeFormat)}`}
|
||||||
|
/>
|
||||||
|
}
|
||||||
</Component>
|
</Component>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -33,6 +46,9 @@ function IndexerStatusCell(props) {
|
|||||||
IndexerStatusCell.propTypes = {
|
IndexerStatusCell.propTypes = {
|
||||||
className: PropTypes.string.isRequired,
|
className: PropTypes.string.isRequired,
|
||||||
enabled: PropTypes.bool.isRequired,
|
enabled: PropTypes.bool.isRequired,
|
||||||
|
status: PropTypes.object,
|
||||||
|
longDateFormat: PropTypes.string.isRequired,
|
||||||
|
timeFormat: PropTypes.string.isRequired,
|
||||||
component: PropTypes.elementType
|
component: PropTypes.elementType
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -68,9 +68,12 @@ class MovieIndexRow extends Component {
|
|||||||
protocol,
|
protocol,
|
||||||
privacy,
|
privacy,
|
||||||
priority,
|
priority,
|
||||||
|
status,
|
||||||
added,
|
added,
|
||||||
capabilities,
|
capabilities,
|
||||||
columns,
|
columns,
|
||||||
|
longDateFormat,
|
||||||
|
timeFormat,
|
||||||
isMovieEditorActive,
|
isMovieEditorActive,
|
||||||
isSelected,
|
isSelected,
|
||||||
onSelectedChange
|
onSelectedChange
|
||||||
@@ -113,6 +116,8 @@ class MovieIndexRow extends Component {
|
|||||||
className={styles[column.name]}
|
className={styles[column.name]}
|
||||||
enabled={enableRss || enableAutomaticSearch || enableInteractiveSearch}
|
enabled={enableRss || enableAutomaticSearch || enableInteractiveSearch}
|
||||||
status={status}
|
status={status}
|
||||||
|
longDateFormat={longDateFormat}
|
||||||
|
timeFormat={timeFormat}
|
||||||
component={VirtualTableRowCell}
|
component={VirtualTableRowCell}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -253,6 +258,7 @@ MovieIndexRow.propTypes = {
|
|||||||
enableRss: PropTypes.bool.isRequired,
|
enableRss: PropTypes.bool.isRequired,
|
||||||
enableAutomaticSearch: PropTypes.bool.isRequired,
|
enableAutomaticSearch: PropTypes.bool.isRequired,
|
||||||
enableInteractiveSearch: PropTypes.bool.isRequired,
|
enableInteractiveSearch: PropTypes.bool.isRequired,
|
||||||
|
status: PropTypes.object,
|
||||||
capabilities: PropTypes.object.isRequired,
|
capabilities: PropTypes.object.isRequired,
|
||||||
added: PropTypes.string.isRequired,
|
added: PropTypes.string.isRequired,
|
||||||
tags: PropTypes.arrayOf(PropTypes.number).isRequired,
|
tags: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||||
@@ -260,7 +266,9 @@ MovieIndexRow.propTypes = {
|
|||||||
isSearchingMovie: PropTypes.bool.isRequired,
|
isSearchingMovie: PropTypes.bool.isRequired,
|
||||||
isMovieEditorActive: PropTypes.bool.isRequired,
|
isMovieEditorActive: PropTypes.bool.isRequired,
|
||||||
isSelected: PropTypes.bool,
|
isSelected: PropTypes.bool,
|
||||||
onSelectedChange: PropTypes.func.isRequired
|
onSelectedChange: PropTypes.func.isRequired,
|
||||||
|
longDateFormat: PropTypes.string.isRequired,
|
||||||
|
timeFormat: PropTypes.string.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
MovieIndexRow.defaultProps = {
|
MovieIndexRow.defaultProps = {
|
||||||
|
@@ -6,6 +6,7 @@ import * as history from './historyActions';
|
|||||||
import * as indexers from './indexerActions';
|
import * as indexers from './indexerActions';
|
||||||
import * as indexerIndex from './indexerIndexActions';
|
import * as indexerIndex from './indexerIndexActions';
|
||||||
import * as indexerStats from './indexerStatsActions';
|
import * as indexerStats from './indexerStatsActions';
|
||||||
|
import * as indexerStatus from './indexerStatusActions';
|
||||||
import * as movies from './movieActions';
|
import * as movies from './movieActions';
|
||||||
import * as oAuth from './oAuthActions';
|
import * as oAuth from './oAuthActions';
|
||||||
import * as paths from './pathActions';
|
import * as paths from './pathActions';
|
||||||
@@ -29,6 +30,7 @@ export default [
|
|||||||
indexers,
|
indexers,
|
||||||
indexerIndex,
|
indexerIndex,
|
||||||
indexerStats,
|
indexerStats,
|
||||||
|
indexerStatus,
|
||||||
settings,
|
settings,
|
||||||
system,
|
system,
|
||||||
tags
|
tags
|
||||||
|
46
frontend/src/Store/Actions/indexerStatusActions.js
Normal file
46
frontend/src/Store/Actions/indexerStatusActions.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { createThunk, handleThunks } from 'Store/thunks';
|
||||||
|
import createFetchHandler from './Creators/createFetchHandler';
|
||||||
|
import createHandleActions from './Creators/createHandleActions';
|
||||||
|
|
||||||
|
//
|
||||||
|
// Variables
|
||||||
|
|
||||||
|
export const section = 'indexerStatus';
|
||||||
|
|
||||||
|
//
|
||||||
|
// State
|
||||||
|
|
||||||
|
export const defaultState = {
|
||||||
|
isFetching: false,
|
||||||
|
isPopulated: false,
|
||||||
|
error: null,
|
||||||
|
items: [],
|
||||||
|
|
||||||
|
details: {
|
||||||
|
isFetching: false,
|
||||||
|
isPopulated: false,
|
||||||
|
error: null,
|
||||||
|
items: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Actions Types
|
||||||
|
|
||||||
|
export const FETCH_INDEXER_STATUS = 'indexerStatus/fetchIndexerStatus';
|
||||||
|
|
||||||
|
//
|
||||||
|
// Action Creators
|
||||||
|
|
||||||
|
export const fetchIndexerStatus = createThunk(FETCH_INDEXER_STATUS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Action Handlers
|
||||||
|
|
||||||
|
export const actionHandlers = handleThunks({
|
||||||
|
[FETCH_INDEXER_STATUS]: createFetchHandler(section, '/indexerStatus')
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reducers
|
||||||
|
export const reducers = createHandleActions({}, defaultState, section);
|
14
frontend/src/Store/Selectors/createIndexerStatusSelector.js
Normal file
14
frontend/src/Store/Selectors/createIndexerStatusSelector.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import _ from 'lodash';
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
|
||||||
|
function createIndexerStatusSelector() {
|
||||||
|
return createSelector(
|
||||||
|
(state, { indexerId }) => indexerId,
|
||||||
|
(state) => state.indexerStatus.items,
|
||||||
|
(indexerId, indexerStatus) => {
|
||||||
|
return _.find(indexerStatus, { indexerId });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createIndexerStatusSelector;
|
@@ -20,6 +20,7 @@ namespace Prowlarr.Api.V1.Indexers
|
|||||||
public IndexerCapabilityResource Capabilities { get; set; }
|
public IndexerCapabilityResource Capabilities { get; set; }
|
||||||
public int Priority { get; set; }
|
public int Priority { get; set; }
|
||||||
public DateTime Added { get; set; }
|
public DateTime Added { get; set; }
|
||||||
|
public IndexerStatusResource Status { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IndexerResourceMapper : ProviderResourceMapper<IndexerResource, IndexerDefinition>
|
public class IndexerResourceMapper : ProviderResourceMapper<IndexerResource, IndexerDefinition>
|
||||||
|
23
src/Prowlarr.Api.V1/Indexers/IndexerStatusModule.cs
Normal file
23
src/Prowlarr.Api.V1/Indexers/IndexerStatusModule.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.Indexers;
|
||||||
|
using Prowlarr.Http;
|
||||||
|
|
||||||
|
namespace Prowlarr.Api.V1.Indexers
|
||||||
|
{
|
||||||
|
public class IndexerStatusModule : ProwlarrRestModule<IndexerStatusResource>
|
||||||
|
{
|
||||||
|
private readonly IIndexerStatusService _indexerStatusService;
|
||||||
|
|
||||||
|
public IndexerStatusModule(IIndexerStatusService indexerStatusService)
|
||||||
|
{
|
||||||
|
_indexerStatusService = indexerStatusService;
|
||||||
|
|
||||||
|
GetResourceAll = GetAll;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<IndexerStatusResource> GetAll()
|
||||||
|
{
|
||||||
|
return _indexerStatusService.GetBlockedProviders().ToResource();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
src/Prowlarr.Api.V1/Indexers/IndexerStatusResource.cs
Normal file
36
src/Prowlarr.Api.V1/Indexers/IndexerStatusResource.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NzbDrone.Core.Indexers;
|
||||||
|
using Prowlarr.Http.REST;
|
||||||
|
|
||||||
|
namespace Prowlarr.Api.V1.Indexers
|
||||||
|
{
|
||||||
|
public class IndexerStatusResource : RestResource
|
||||||
|
{
|
||||||
|
public int IndexerId { get; set; }
|
||||||
|
public DateTime? DisabledTill { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class IndexerStatusResourceMapper
|
||||||
|
{
|
||||||
|
public static IndexerStatusResource ToResource(this IndexerStatus model)
|
||||||
|
{
|
||||||
|
if (model == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new IndexerStatusResource
|
||||||
|
{
|
||||||
|
IndexerId = model.ProviderId,
|
||||||
|
DisabledTill = model.DisabledTill
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<IndexerStatusResource> ToResource(this IEnumerable<IndexerStatus> models)
|
||||||
|
{
|
||||||
|
return models.Select(ToResource).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user