mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
Add Encoding, Language, Description Indexer props
This commit is contained in:
@@ -9,6 +9,7 @@ import TagListConnector from 'Components/TagListConnector';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import DeleteIndexerModal from 'Indexer/Delete/DeleteIndexerModal';
|
||||
import EditIndexerModalConnector from 'Indexer/Edit/EditIndexerModalConnector';
|
||||
import IndexerInfoModal from 'Indexer/Info/IndexerInfoModal';
|
||||
import titleCase from 'Utilities/String/titleCase';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import CapabilitiesLabel from './CapabilitiesLabel';
|
||||
@@ -26,7 +27,8 @@ class IndexerIndexRow extends Component {
|
||||
|
||||
this.state = {
|
||||
isEditIndexerModalOpen: false,
|
||||
isDeleteMovieModalOpen: false
|
||||
isDeleteMovieModalOpen: false,
|
||||
isIndexerInfoModalOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
@@ -34,10 +36,18 @@ class IndexerIndexRow extends Component {
|
||||
this.setState({ isEditIndexerModalOpen: true });
|
||||
}
|
||||
|
||||
onIndexerInfoPress = () => {
|
||||
this.setState({ isIndexerInfoModalOpen: true });
|
||||
}
|
||||
|
||||
onEditIndexerModalClose = () => {
|
||||
this.setState({ isEditIndexerModalOpen: false });
|
||||
}
|
||||
|
||||
onIndexerInfoModalClose = () => {
|
||||
this.setState({ isIndexerInfoModalOpen: false });
|
||||
}
|
||||
|
||||
onDeleteMoviePress = () => {
|
||||
this.setState({
|
||||
isEditIndexerModalOpen: false,
|
||||
@@ -81,7 +91,8 @@ class IndexerIndexRow extends Component {
|
||||
|
||||
const {
|
||||
isEditIndexerModalOpen,
|
||||
isDeleteMovieModalOpen
|
||||
isDeleteMovieModalOpen,
|
||||
isIndexerInfoModalOpen
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
@@ -215,6 +226,12 @@ class IndexerIndexRow extends Component {
|
||||
key={column.name}
|
||||
className={styles[column.name]}
|
||||
>
|
||||
<IconButton
|
||||
name={icons.INFO}
|
||||
title={'Indexer info'}
|
||||
onPress={this.onIndexerInfoPress}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
className={styles.externalLink}
|
||||
name={icons.EXTERNAL_LINK}
|
||||
@@ -242,6 +259,12 @@ class IndexerIndexRow extends Component {
|
||||
onDeleteIndexerPress={this.onDeleteMoviePress}
|
||||
/>
|
||||
|
||||
<IndexerInfoModal
|
||||
indexerId={id}
|
||||
isOpen={isIndexerInfoModalOpen}
|
||||
onModalClose={this.onIndexerInfoModalClose}
|
||||
/>
|
||||
|
||||
<DeleteIndexerModal
|
||||
isOpen={isDeleteMovieModalOpen}
|
||||
indexerId={id}
|
||||
|
27
frontend/src/Indexer/Info/IndexerInfoModal.js
Normal file
27
frontend/src/Indexer/Info/IndexerInfoModal.js
Normal 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;
|
5
frontend/src/Indexer/Info/IndexerInfoModalContent.css
Normal file
5
frontend/src/Indexer/Info/IndexerInfoModalContent.css
Normal file
@@ -0,0 +1,5 @@
|
||||
.description {
|
||||
composes: description from '~Components/DescriptionList/DescriptionListItemDescription.css';
|
||||
|
||||
overflow-wrap: break-word;
|
||||
}
|
82
frontend/src/Indexer/Info/IndexerInfoModalContent.js
Normal file
82
frontend/src/Indexer/Info/IndexerInfoModalContent.js
Normal 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;
|
@@ -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);
|
@@ -5,9 +5,9 @@ function createIndexerSelector() {
|
||||
(state, { indexerId }) => indexerId,
|
||||
(state) => state.indexers.itemMap,
|
||||
(state) => state.indexers.items,
|
||||
(indexerId, itemMap, allMovies) => {
|
||||
if (allMovies && itemMap && indexerId in itemMap) {
|
||||
return allMovies[itemMap[indexerId]];
|
||||
(indexerId, itemMap, allIndexers) => {
|
||||
if (allIndexers && itemMap && indexerId in itemMap) {
|
||||
return allIndexers[itemMap[indexerId]];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
@@ -41,6 +41,9 @@ namespace NzbDrone.Core.Datastore
|
||||
|
||||
Mapper.Entity<IndexerDefinition>("Indexers").RegisterModel()
|
||||
.Ignore(x => x.ImplementationName)
|
||||
.Ignore(i => i.Description)
|
||||
.Ignore(i => i.Language)
|
||||
.Ignore(i => i.Encoding)
|
||||
.Ignore(i => i.BaseUrl)
|
||||
.Ignore(i => i.Protocol)
|
||||
.Ignore(i => i.Privacy)
|
||||
|
@@ -128,6 +128,11 @@ namespace NzbDrone.Core.IndexerVersions
|
||||
};
|
||||
}
|
||||
|
||||
if (definition.Encoding == null)
|
||||
{
|
||||
definition.Encoding = "UTF-8";
|
||||
}
|
||||
|
||||
if (definition.Login != null && definition.Login.Method == null)
|
||||
{
|
||||
definition.Login.Method = "form";
|
||||
|
@@ -10,6 +10,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
{
|
||||
public override string Name => "AlphaRatio";
|
||||
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 AlphaRatio(IHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger)
|
||||
|
@@ -33,6 +33,12 @@ namespace NzbDrone.Core.Indexers
|
||||
public override bool SupportsSearch => true;
|
||||
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 IndexerCapabilities Capabilities { get; protected set; }
|
||||
public virtual int PageSize => 0;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
@@ -13,6 +14,9 @@ namespace NzbDrone.Core.Indexers
|
||||
IndexerCapabilities Capabilities { get; }
|
||||
|
||||
string BaseUrl { get; }
|
||||
string Description { get; }
|
||||
Encoding Encoding { get; }
|
||||
string Language { get; }
|
||||
DownloadProtocol Protocol { get; }
|
||||
IndexerPrivacy Privacy { get; }
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
@@ -21,6 +22,9 @@ namespace NzbDrone.Core.Indexers
|
||||
|
||||
public abstract string Name { 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 DownloadProtocol Protocol { get; }
|
||||
public abstract IndexerPrivacy Privacy { get; }
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NzbDrone.Core.Indexers.Cardigann;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
|
||||
@@ -8,6 +9,9 @@ namespace NzbDrone.Core.Indexers
|
||||
public class IndexerDefinition : ProviderDefinition
|
||||
{
|
||||
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 IndexerPrivacy Privacy { get; set; }
|
||||
public bool SupportsRss { get; set; }
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Indexers.Cardigann;
|
||||
@@ -90,6 +91,9 @@ namespace NzbDrone.Core.Indexers
|
||||
}
|
||||
|
||||
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.Capabilities = new IndexerCapabilities();
|
||||
definition.Capabilities.ParseCardigannSearchModes(defFile.Caps.Modes);
|
||||
@@ -172,6 +176,9 @@ namespace NzbDrone.Core.Indexers
|
||||
{
|
||||
definition.BaseUrl = provider.BaseUrl;
|
||||
definition.Privacy = provider.Privacy;
|
||||
definition.Description = provider.Description;
|
||||
definition.Encoding = provider.Encoding;
|
||||
definition.Language = provider.Language;
|
||||
definition.Capabilities = provider.Capabilities;
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Indexers;
|
||||
@@ -13,6 +14,9 @@ namespace Prowlarr.Api.V1.Indexers
|
||||
public class IndexerResource : ProviderResource<IndexerResource>
|
||||
{
|
||||
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 Redirect { get; set; }
|
||||
public bool SupportsRss { get; set; }
|
||||
@@ -62,6 +66,9 @@ namespace Prowlarr.Api.V1.Indexers
|
||||
}
|
||||
|
||||
resource.BaseUrl = definition.BaseUrl;
|
||||
resource.Description = definition.Description;
|
||||
resource.Language = definition.Language;
|
||||
resource.Encoding = definition.Encoding.EncodingName;
|
||||
resource.Enable = definition.Enable;
|
||||
resource.Redirect = definition.Redirect;
|
||||
resource.SupportsRss = definition.SupportsRss;
|
||||
|
Reference in New Issue
Block a user