Add Encoding, Language, Description Indexer props

This commit is contained in:
Qstick
2021-04-25 23:30:52 -04:00
parent afe1d695d0
commit c6c1644d00
15 changed files with 224 additions and 5 deletions

View File

@@ -9,6 +9,7 @@ import TagListConnector from 'Components/TagListConnector';
import { icons } from 'Helpers/Props'; import { icons } from 'Helpers/Props';
import DeleteIndexerModal from 'Indexer/Delete/DeleteIndexerModal'; import DeleteIndexerModal from 'Indexer/Delete/DeleteIndexerModal';
import EditIndexerModalConnector from 'Indexer/Edit/EditIndexerModalConnector'; import EditIndexerModalConnector from 'Indexer/Edit/EditIndexerModalConnector';
import IndexerInfoModal from 'Indexer/Info/IndexerInfoModal';
import titleCase from 'Utilities/String/titleCase'; import titleCase from 'Utilities/String/titleCase';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import CapabilitiesLabel from './CapabilitiesLabel'; import CapabilitiesLabel from './CapabilitiesLabel';
@@ -26,7 +27,8 @@ class IndexerIndexRow extends Component {
this.state = { this.state = {
isEditIndexerModalOpen: false, isEditIndexerModalOpen: false,
isDeleteMovieModalOpen: false isDeleteMovieModalOpen: false,
isIndexerInfoModalOpen: false
}; };
} }
@@ -34,10 +36,18 @@ class IndexerIndexRow extends Component {
this.setState({ isEditIndexerModalOpen: true }); this.setState({ isEditIndexerModalOpen: true });
} }
onIndexerInfoPress = () => {
this.setState({ isIndexerInfoModalOpen: true });
}
onEditIndexerModalClose = () => { onEditIndexerModalClose = () => {
this.setState({ isEditIndexerModalOpen: false }); this.setState({ isEditIndexerModalOpen: false });
} }
onIndexerInfoModalClose = () => {
this.setState({ isIndexerInfoModalOpen: false });
}
onDeleteMoviePress = () => { onDeleteMoviePress = () => {
this.setState({ this.setState({
isEditIndexerModalOpen: false, isEditIndexerModalOpen: false,
@@ -81,7 +91,8 @@ class IndexerIndexRow extends Component {
const { const {
isEditIndexerModalOpen, isEditIndexerModalOpen,
isDeleteMovieModalOpen isDeleteMovieModalOpen,
isIndexerInfoModalOpen
} = this.state; } = this.state;
return ( return (
@@ -215,6 +226,12 @@ class IndexerIndexRow extends Component {
key={column.name} key={column.name}
className={styles[column.name]} className={styles[column.name]}
> >
<IconButton
name={icons.INFO}
title={'Indexer info'}
onPress={this.onIndexerInfoPress}
/>
<IconButton <IconButton
className={styles.externalLink} className={styles.externalLink}
name={icons.EXTERNAL_LINK} name={icons.EXTERNAL_LINK}
@@ -242,6 +259,12 @@ class IndexerIndexRow extends Component {
onDeleteIndexerPress={this.onDeleteMoviePress} onDeleteIndexerPress={this.onDeleteMoviePress}
/> />
<IndexerInfoModal
indexerId={id}
isOpen={isIndexerInfoModalOpen}
onModalClose={this.onIndexerInfoModalClose}
/>
<DeleteIndexerModal <DeleteIndexerModal
isOpen={isDeleteMovieModalOpen} isOpen={isDeleteMovieModalOpen}
indexerId={id} indexerId={id}

View File

@@ -0,0 +1,27 @@
import PropTypes from 'prop-types';
import React from 'react';
import Modal from 'Components/Modal/Modal';
import { sizes } from 'Helpers/Props';
import IndexerInfoModalContentConnector from './IndexerInfoModalContentConnector';
function IndexerInfoModal({ isOpen, onModalClose, ...otherProps }) {
return (
<Modal
size={sizes.MEDIUM}
isOpen={isOpen}
onModalClose={onModalClose}
>
<IndexerInfoModalContentConnector
{...otherProps}
onModalClose={onModalClose}
/>
</Modal>
);
}
IndexerInfoModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default IndexerInfoModal;

View File

@@ -0,0 +1,5 @@
.description {
composes: description from '~Components/DescriptionList/DescriptionListItemDescription.css';
overflow-wrap: break-word;
}

View File

@@ -0,0 +1,82 @@
import PropTypes from 'prop-types';
import React from 'react';
import DescriptionList from 'Components/DescriptionList/DescriptionList';
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
import DescriptionListItemDescription from 'Components/DescriptionList/DescriptionListItemDescription';
import DescriptionListItemTitle from 'Components/DescriptionList/DescriptionListItemTitle';
import Link from 'Components/Link/Link';
import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent';
import ModalHeader from 'Components/Modal/ModalHeader';
import translate from 'Utilities/String/translate';
import styles from './IndexerInfoModalContent.css';
function IndexerInfoModalContent(props) {
const {
id,
name,
description,
encoding,
language,
baseUrl,
protocol,
onModalClose
} = props;
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{`${name}`}
</ModalHeader>
<ModalBody>
<DescriptionList>
<DescriptionListItem
descriptionClassName={styles.description}
title={translate('Id')}
data={id}
/>
<DescriptionListItem
descriptionClassName={styles.description}
title={translate('Description')}
data={description ? description : '-'}
/>
<DescriptionListItem
descriptionClassName={styles.description}
title={translate('Encoding')}
data={encoding ? encoding : '-'}
/>
<DescriptionListItem
descriptionClassName={styles.description}
title={translate('Language')}
data={language ?? '-'}
/>
<DescriptionListItemTitle>Indexer Site</DescriptionListItemTitle>
<DescriptionListItemDescription>
<Link to={baseUrl}>{baseUrl}</Link>
</DescriptionListItemDescription>
<DescriptionListItemTitle>{protocol === 'usenet' ? 'Newznab' : 'Torznab'} Url</DescriptionListItemTitle>
<DescriptionListItemDescription>
{`${window.Prowlarr.apiRoot}/indexer/${id}/newznab`}
</DescriptionListItemDescription>
</DescriptionList>
</ModalBody>
</ModalContent>
);
}
IndexerInfoModalContent.propTypes = {
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
description: PropTypes.string.isRequired,
encoding: PropTypes.string.isRequired,
language: PropTypes.string.isRequired,
baseUrl: PropTypes.string.isRequired,
protocol: PropTypes.string.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default IndexerInfoModalContent;

View File

@@ -0,0 +1,41 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createIndexerSelector from 'Store/Selectors/createIndexerSelector';
import IndexerInfoModalContent from './IndexerInfoModalContent';
function createMapStateToProps() {
return createSelector(
(state) => state.settings.advancedSettings,
createIndexerSelector(),
(advancedSettings, indexer) => {
console.log(indexer);
return {
advancedSettings,
...indexer
};
}
);
}
class IndexerInfoModalContentConnector extends Component {
//
// Render
render() {
return (
<IndexerInfoModalContent
{...this.props}
/>
);
}
}
IndexerInfoModalContentConnector.propTypes = {
indexerId: PropTypes.number,
onModalClose: PropTypes.func.isRequired
};
export default connect(createMapStateToProps)(IndexerInfoModalContentConnector);

View File

@@ -5,9 +5,9 @@ function createIndexerSelector() {
(state, { indexerId }) => indexerId, (state, { indexerId }) => indexerId,
(state) => state.indexers.itemMap, (state) => state.indexers.itemMap,
(state) => state.indexers.items, (state) => state.indexers.items,
(indexerId, itemMap, allMovies) => { (indexerId, itemMap, allIndexers) => {
if (allMovies && itemMap && indexerId in itemMap) { if (allIndexers && itemMap && indexerId in itemMap) {
return allMovies[itemMap[indexerId]]; return allIndexers[itemMap[indexerId]];
} }
return undefined; return undefined;
} }

View File

@@ -41,6 +41,9 @@ namespace NzbDrone.Core.Datastore
Mapper.Entity<IndexerDefinition>("Indexers").RegisterModel() Mapper.Entity<IndexerDefinition>("Indexers").RegisterModel()
.Ignore(x => x.ImplementationName) .Ignore(x => x.ImplementationName)
.Ignore(i => i.Description)
.Ignore(i => i.Language)
.Ignore(i => i.Encoding)
.Ignore(i => i.BaseUrl) .Ignore(i => i.BaseUrl)
.Ignore(i => i.Protocol) .Ignore(i => i.Protocol)
.Ignore(i => i.Privacy) .Ignore(i => i.Privacy)

View File

@@ -128,6 +128,11 @@ namespace NzbDrone.Core.IndexerVersions
}; };
} }
if (definition.Encoding == null)
{
definition.Encoding = "UTF-8";
}
if (definition.Login != null && definition.Login.Method == null) if (definition.Login != null && definition.Login.Method == null)
{ {
definition.Login.Method = "form"; definition.Login.Method = "form";

View File

@@ -10,6 +10,7 @@ namespace NzbDrone.Core.Indexers.Definitions
{ {
public override string Name => "AlphaRatio"; public override string Name => "AlphaRatio";
public override string BaseUrl => "https://alpharatio.cc/"; public override string BaseUrl => "https://alpharatio.cc/";
public override string Description => "AlphaRatio(AR) is a Private Torrent Tracker for 0DAY / GENERAL";
public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
public AlphaRatio(IHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger) public AlphaRatio(IHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger)

View File

@@ -33,6 +33,12 @@ namespace NzbDrone.Core.Indexers
public override bool SupportsSearch => true; public override bool SupportsSearch => true;
public override bool SupportsRedirect => false; public override bool SupportsRedirect => false;
public override Encoding Encoding => Encoding.UTF8;
public override string Language => "en-US";
//TODO Remove this once we catch up on individual indexers
public override string Description => "";
public override bool FollowRedirect => false; public override bool FollowRedirect => false;
public override IndexerCapabilities Capabilities { get; protected set; } public override IndexerCapabilities Capabilities { get; protected set; }
public virtual int PageSize => 0; public virtual int PageSize => 0;

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
@@ -13,6 +14,9 @@ namespace NzbDrone.Core.Indexers
IndexerCapabilities Capabilities { get; } IndexerCapabilities Capabilities { get; }
string BaseUrl { get; } string BaseUrl { get; }
string Description { get; }
Encoding Encoding { get; }
string Language { get; }
DownloadProtocol Protocol { get; } DownloadProtocol Protocol { get; }
IndexerPrivacy Privacy { get; } IndexerPrivacy Privacy { get; }

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentValidation.Results; using FluentValidation.Results;
using NLog; using NLog;
@@ -21,6 +22,9 @@ namespace NzbDrone.Core.Indexers
public abstract string Name { get; } public abstract string Name { get; }
public abstract string BaseUrl { get; } public abstract string BaseUrl { get; }
public abstract string Description { get; }
public abstract Encoding Encoding { get; }
public abstract string Language { get; }
public abstract bool FollowRedirect { get; } public abstract bool FollowRedirect { get; }
public abstract DownloadProtocol Protocol { get; } public abstract DownloadProtocol Protocol { get; }
public abstract IndexerPrivacy Privacy { get; } public abstract IndexerPrivacy Privacy { get; }

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using NzbDrone.Core.Indexers.Cardigann; using NzbDrone.Core.Indexers.Cardigann;
using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.ThingiProvider;
@@ -8,6 +9,9 @@ namespace NzbDrone.Core.Indexers
public class IndexerDefinition : ProviderDefinition public class IndexerDefinition : ProviderDefinition
{ {
public string BaseUrl { get; set; } public string BaseUrl { get; set; }
public string Description { get; set; }
public Encoding Encoding { get; set; }
public string Language { get; set; }
public DownloadProtocol Protocol { get; set; } public DownloadProtocol Protocol { get; set; }
public IndexerPrivacy Privacy { get; set; } public IndexerPrivacy Privacy { get; set; }
public bool SupportsRss { get; set; } public bool SupportsRss { get; set; }

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using FluentValidation.Results; using FluentValidation.Results;
using NLog; using NLog;
using NzbDrone.Core.Indexers.Cardigann; using NzbDrone.Core.Indexers.Cardigann;
@@ -90,6 +91,9 @@ namespace NzbDrone.Core.Indexers
} }
definition.BaseUrl = defFile.Links.First(); definition.BaseUrl = defFile.Links.First();
definition.Description = defFile.Description;
definition.Language = defFile.Language;
definition.Encoding = Encoding.GetEncoding(defFile.Encoding);
definition.Privacy = defFile.Type == "private" ? IndexerPrivacy.Private : IndexerPrivacy.Public; definition.Privacy = defFile.Type == "private" ? IndexerPrivacy.Private : IndexerPrivacy.Public;
definition.Capabilities = new IndexerCapabilities(); definition.Capabilities = new IndexerCapabilities();
definition.Capabilities.ParseCardigannSearchModes(defFile.Caps.Modes); definition.Capabilities.ParseCardigannSearchModes(defFile.Caps.Modes);
@@ -172,6 +176,9 @@ namespace NzbDrone.Core.Indexers
{ {
definition.BaseUrl = provider.BaseUrl; definition.BaseUrl = provider.BaseUrl;
definition.Privacy = provider.Privacy; definition.Privacy = provider.Privacy;
definition.Description = provider.Description;
definition.Encoding = provider.Encoding;
definition.Language = provider.Language;
definition.Capabilities = provider.Capabilities; definition.Capabilities = provider.Capabilities;
} }
} }

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations; using NzbDrone.Core.Annotations;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
@@ -13,6 +14,9 @@ namespace Prowlarr.Api.V1.Indexers
public class IndexerResource : ProviderResource<IndexerResource> public class IndexerResource : ProviderResource<IndexerResource>
{ {
public string BaseUrl { get; set; } public string BaseUrl { get; set; }
public string Description { get; set; }
public string Language { get; set; }
public string Encoding { get; set; }
public bool Enable { get; set; } public bool Enable { get; set; }
public bool Redirect { get; set; } public bool Redirect { get; set; }
public bool SupportsRss { get; set; } public bool SupportsRss { get; set; }
@@ -62,6 +66,9 @@ namespace Prowlarr.Api.V1.Indexers
} }
resource.BaseUrl = definition.BaseUrl; resource.BaseUrl = definition.BaseUrl;
resource.Description = definition.Description;
resource.Language = definition.Language;
resource.Encoding = definition.Encoding.EncodingName;
resource.Enable = definition.Enable; resource.Enable = definition.Enable;
resource.Redirect = definition.Redirect; resource.Redirect = definition.Redirect;
resource.SupportsRss = definition.SupportsRss; resource.SupportsRss = definition.SupportsRss;