mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2026-03-10 15:30:14 -04:00
Compare commits
1 Commits
v0.2.0.144
...
http2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa304dcaca |
@@ -7,7 +7,7 @@ variables:
|
||||
outputFolder: './_output'
|
||||
artifactsFolder: './_artifacts'
|
||||
testsFolder: './_tests'
|
||||
majorVersion: '0.2.0'
|
||||
majorVersion: '0.1.10'
|
||||
minorVersion: $[counter('minorVersion', 1)]
|
||||
prowlarrVersion: '$(majorVersion).$(minorVersion)'
|
||||
buildName: '$(Build.SourceBranchName).$(prowlarrVersion)'
|
||||
|
||||
@@ -8,7 +8,6 @@ import BoolFilterBuilderRowValue from './BoolFilterBuilderRowValue';
|
||||
import DateFilterBuilderRowValue from './DateFilterBuilderRowValue';
|
||||
import FilterBuilderRowValueConnector from './FilterBuilderRowValueConnector';
|
||||
import IndexerFilterBuilderRowValueConnector from './IndexerFilterBuilderRowValueConnector';
|
||||
import PrivacyFilterBuilderRowValue from './PrivacyFilterBuilderRowValue';
|
||||
import ProtocolFilterBuilderRowValue from './ProtocolFilterBuilderRowValue';
|
||||
import TagFilterBuilderRowValueConnector from './TagFilterBuilderRowValueConnector';
|
||||
import styles from './FilterBuilderRow.css';
|
||||
@@ -64,9 +63,6 @@ function getRowValueConnector(selectedFilterBuilderProp) {
|
||||
case filterBuilderValueTypes.PROTOCOL:
|
||||
return ProtocolFilterBuilderRowValue;
|
||||
|
||||
case filterBuilderValueTypes.PRIVACY:
|
||||
return PrivacyFilterBuilderRowValue;
|
||||
|
||||
case filterBuilderValueTypes.TAG:
|
||||
return TagFilterBuilderRowValueConnector;
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import React from 'react';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import FilterBuilderRowValue from './FilterBuilderRowValue';
|
||||
|
||||
const privacyTypes = [
|
||||
{ id: 'public', name: translate('Public') },
|
||||
{ id: 'private', name: translate('Private') },
|
||||
{ id: 'semiPrivate', name: translate('SemiPrivate') }
|
||||
];
|
||||
|
||||
function PrivacyFilterBuilderRowValue(props) {
|
||||
return (
|
||||
<FilterBuilderRowValue
|
||||
tagList={privacyTypes}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default PrivacyFilterBuilderRowValue;
|
||||
@@ -4,7 +4,6 @@ export const DATE = 'date';
|
||||
export const DEFAULT = 'default';
|
||||
export const INDEXER = 'indexer';
|
||||
export const PROTOCOL = 'protocol';
|
||||
export const PRIVACY = 'privacy';
|
||||
export const APP_PROFILE = 'appProfile';
|
||||
export const MOVIE_STATUS = 'movieStatus';
|
||||
export const TAG = 'tag';
|
||||
|
||||
@@ -4,7 +4,7 @@ import Modal from 'Components/Modal/Modal';
|
||||
import AddIndexerModalContentConnector from './AddIndexerModalContentConnector';
|
||||
import styles from './AddIndexerModal.css';
|
||||
|
||||
function AddIndexerModal({ isOpen, onModalClose, onSelectIndexer, ...otherProps }) {
|
||||
function AddIndexerModal({ isOpen, onModalClose, ...otherProps }) {
|
||||
return (
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
@@ -14,7 +14,6 @@ function AddIndexerModal({ isOpen, onModalClose, onSelectIndexer, ...otherProps
|
||||
<AddIndexerModalContentConnector
|
||||
{...otherProps}
|
||||
onModalClose={onModalClose}
|
||||
onSelectIndexer={onSelectIndexer}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
@@ -22,8 +21,7 @@ function AddIndexerModal({ isOpen, onModalClose, onSelectIndexer, ...otherProps
|
||||
|
||||
AddIndexerModal.propTypes = {
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
onModalClose: PropTypes.func.isRequired,
|
||||
onSelectIndexer: PropTypes.func.isRequired
|
||||
onModalClose: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default AddIndexerModal;
|
||||
|
||||
@@ -15,7 +15,7 @@ import TableBody from 'Components/Table/TableBody';
|
||||
import { kinds, scrollDirections } from 'Helpers/Props';
|
||||
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import SelectIndexerRowConnector from './SelectIndexerRowConnector';
|
||||
import SelectIndexerRow from './SelectIndexerRow';
|
||||
import styles from './AddIndexerModalContent.css';
|
||||
|
||||
const columns = [
|
||||
@@ -219,7 +219,7 @@ class AddIndexerModalContent extends Component {
|
||||
<TableBody>
|
||||
{
|
||||
filteredIndexers.map((indexer) => (
|
||||
<SelectIndexerRowConnector
|
||||
<SelectIndexerRow
|
||||
key={indexer.name}
|
||||
implementation={indexer.implementation}
|
||||
{...indexer}
|
||||
|
||||
@@ -51,7 +51,7 @@ class AddIndexerModalContentConnector extends Component {
|
||||
|
||||
onIndexerSelect = ({ implementation, name }) => {
|
||||
this.props.selectIndexerSchema({ implementation, name });
|
||||
this.props.onSelectIndexer();
|
||||
this.props.onModalClose({ indexerSelected: true });
|
||||
};
|
||||
|
||||
onSortPress = (sortKey, sortDirection) => {
|
||||
@@ -76,8 +76,7 @@ AddIndexerModalContentConnector.propTypes = {
|
||||
fetchIndexerSchema: PropTypes.func.isRequired,
|
||||
selectIndexerSchema: PropTypes.func.isRequired,
|
||||
setIndexerSchemaSort: PropTypes.func.isRequired,
|
||||
onModalClose: PropTypes.func.isRequired,
|
||||
onSelectIndexer: PropTypes.func.isRequired
|
||||
onModalClose: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(AddIndexerModalContentConnector);
|
||||
|
||||
@@ -3,9 +3,3 @@
|
||||
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.alreadyExistsIcon {
|
||||
margin-left: 10px;
|
||||
color: #37bc9b;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import Icon from 'Components/Icon';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableRowButton from 'Components/Table/TableRowButton';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import ProtocolLabel from 'Indexer/Index/Table/ProtocolLabel';
|
||||
import firstCharToUpper from 'Utilities/String/firstCharToUpper';
|
||||
import translate from 'Utilities/String/translate';
|
||||
@@ -31,8 +29,7 @@ class SelectIndexerRow extends Component {
|
||||
protocol,
|
||||
privacy,
|
||||
name,
|
||||
language,
|
||||
isExistingIndexer
|
||||
language
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@@ -45,16 +42,6 @@ class SelectIndexerRow extends Component {
|
||||
|
||||
<TableRowCell>
|
||||
{name}
|
||||
{
|
||||
isExistingIndexer ?
|
||||
<Icon
|
||||
className={styles.alreadyExistsIcon}
|
||||
name={icons.CHECK_CIRCLE}
|
||||
size={15}
|
||||
title={translate('IndexerAlreadySetup')}
|
||||
/> :
|
||||
null
|
||||
}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell>
|
||||
@@ -75,8 +62,7 @@ SelectIndexerRow.propTypes = {
|
||||
privacy: PropTypes.string.isRequired,
|
||||
language: PropTypes.string.isRequired,
|
||||
implementation: PropTypes.string.isRequired,
|
||||
onIndexerSelect: PropTypes.func.isRequired,
|
||||
isExistingIndexer: PropTypes.bool.isRequired
|
||||
onIndexerSelect: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default SelectIndexerRow;
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import createExistingIndexerSelector from 'Store/Selectors/createExistingIndexerSelector';
|
||||
import SelectIndexerRow from './SelectIndexerRow';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createExistingIndexerSelector(),
|
||||
(isExistingIndexer, dimensions) => {
|
||||
return {
|
||||
isExistingIndexer
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(createMapStateToProps)(SelectIndexerRow);
|
||||
@@ -39,7 +39,6 @@ function EditIndexerModalContent(props) {
|
||||
const {
|
||||
id,
|
||||
implementationName,
|
||||
definitionName,
|
||||
name,
|
||||
enable,
|
||||
redirect,
|
||||
@@ -51,12 +50,10 @@ function EditIndexerModalContent(props) {
|
||||
priority
|
||||
} = item;
|
||||
|
||||
const indexerDisplayName = implementationName === definitionName ? implementationName : `${implementationName} (${definitionName})`;
|
||||
|
||||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
<ModalHeader>
|
||||
{`${id ? translate('EditIndexer') : translate('AddIndexer')} - ${indexerDisplayName}`}
|
||||
{`${id ? translate('EditIndexer') : translate('AddIndexer')} - ${implementationName}`}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
|
||||
@@ -193,12 +193,11 @@ class IndexerIndex extends Component {
|
||||
this.setState({ isAddIndexerModalOpen: true });
|
||||
};
|
||||
|
||||
onAddIndexerModalClose = () => {
|
||||
this.setState({ isAddIndexerModalOpen: false });
|
||||
};
|
||||
|
||||
onAddIndexerSelectIndexer = () => {
|
||||
this.setState({ isEditIndexerModalOpen: true });
|
||||
onAddIndexerModalClose = ({ indexerSelected = false } = {}) => {
|
||||
this.setState({
|
||||
isAddIndexerModalOpen: false,
|
||||
isEditIndexerModalOpen: indexerSelected
|
||||
});
|
||||
};
|
||||
|
||||
onEditIndexerModalClose = () => {
|
||||
@@ -464,7 +463,6 @@ class IndexerIndex extends Component {
|
||||
<AddIndexerModal
|
||||
isOpen={isAddIndexerModalOpen}
|
||||
onModalClose={this.onAddIndexerModalClose}
|
||||
onSelectIndexer={this.onAddIndexerSelectIndexer}
|
||||
/>
|
||||
|
||||
<EditIndexerModalConnector
|
||||
|
||||
@@ -244,15 +244,12 @@ class IndexerIndexRow extends Component {
|
||||
onPress={this.onIndexerInfoPress}
|
||||
/>
|
||||
|
||||
{
|
||||
indexerUrls ?
|
||||
<IconButton
|
||||
className={styles.externalLink}
|
||||
name={icons.EXTERNAL_LINK}
|
||||
title={translate('Website')}
|
||||
to={indexerUrls[0].replace('api.', '')}
|
||||
/> : null
|
||||
}
|
||||
<IconButton
|
||||
className={styles.externalLink}
|
||||
name={icons.EXTERNAL_LINK}
|
||||
title={translate('Website')}
|
||||
to={indexerUrls[0].replace('api.', '')}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
name={icons.EDIT}
|
||||
@@ -292,7 +289,7 @@ class IndexerIndexRow extends Component {
|
||||
|
||||
IndexerIndexRow.propTypes = {
|
||||
id: PropTypes.number.isRequired,
|
||||
indexerUrls: PropTypes.arrayOf(PropTypes.string),
|
||||
indexerUrls: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
protocol: PropTypes.string.isRequired,
|
||||
privacy: PropTypes.string.isRequired,
|
||||
priority: PropTypes.number.isRequired,
|
||||
@@ -301,7 +298,7 @@ IndexerIndexRow.propTypes = {
|
||||
redirect: PropTypes.bool.isRequired,
|
||||
appProfile: PropTypes.object.isRequired,
|
||||
status: PropTypes.object,
|
||||
capabilities: PropTypes.object,
|
||||
capabilities: PropTypes.object.isRequired,
|
||||
added: PropTypes.string.isRequired,
|
||||
tags: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
|
||||
@@ -118,12 +118,12 @@ export const defaultState = {
|
||||
filterBuilderProps: [
|
||||
{
|
||||
name: 'name',
|
||||
label: translate('IndexerName'),
|
||||
label: 'Indexer Name',
|
||||
type: filterBuilderTypes.STRING
|
||||
},
|
||||
{
|
||||
name: 'enable',
|
||||
label: translate('Enabled'),
|
||||
label: 'Enabled',
|
||||
type: filterBuilderTypes.EXACT,
|
||||
valueType: filterBuilderValueTypes.BOOL
|
||||
},
|
||||
@@ -135,21 +135,15 @@ export const defaultState = {
|
||||
},
|
||||
{
|
||||
name: 'priority',
|
||||
label: translate('Priority'),
|
||||
label: 'Priority',
|
||||
type: filterBuilderTypes.NUMBER
|
||||
},
|
||||
{
|
||||
name: 'protocol',
|
||||
label: translate('Protocol'),
|
||||
label: 'Protocol',
|
||||
type: filterBuilderTypes.EXACT,
|
||||
valueType: filterBuilderValueTypes.PROTOCOL
|
||||
},
|
||||
{
|
||||
name: 'privacy',
|
||||
label: translate('Privacy'),
|
||||
type: filterBuilderTypes.EXACT,
|
||||
valueType: filterBuilderValueTypes.PRIVACY
|
||||
},
|
||||
{
|
||||
name: 'appProfileId',
|
||||
label: translate('AppProfile'),
|
||||
|
||||
@@ -80,8 +80,8 @@ export default function createSentryMiddleware() {
|
||||
return;
|
||||
}
|
||||
|
||||
const dsn = isProduction ? 'https://b233094711fe4430a0b0c5da2e01df93@sentry.servarr.com/28' :
|
||||
'https://116efebd253a4dff9df9475a31510001@sentry.servarr.com/37';
|
||||
const dsn = isProduction ? 'https://b0fb75c38ef4487dbf742f79c4ba62d2@sentry.servarr.com/12' :
|
||||
'https://da610619280249f891ec3ee306906793@sentry.servarr.com/13';
|
||||
|
||||
sentry.init({
|
||||
dsn,
|
||||
|
||||
14
frontend/src/Store/Selectors/createExclusionMovieSelector.js
Normal file
14
frontend/src/Store/Selectors/createExclusionMovieSelector.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import _ from 'lodash';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
function createExclusionMovieSelector() {
|
||||
return createSelector(
|
||||
(state, { tmdbId }) => tmdbId,
|
||||
(state) => state.settings.importExclusions,
|
||||
(tmdbId, importExclusions) => {
|
||||
return _.some(importExclusions.items, { tmdbId });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default createExclusionMovieSelector;
|
||||
@@ -1,15 +0,0 @@
|
||||
import _ from 'lodash';
|
||||
import { createSelector } from 'reselect';
|
||||
import createAllIndexersSelector from './createAllIndexersSelector';
|
||||
|
||||
function createExistingIndexerSelector() {
|
||||
return createSelector(
|
||||
(state, { definitionName }) => definitionName,
|
||||
createAllIndexersSelector(),
|
||||
(definitionName, indexers) => {
|
||||
return _.some(indexers, { definitionName });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default createExistingIndexerSelector;
|
||||
@@ -36,12 +36,6 @@ function selectSettings(item, pendingChanges, saveError) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (key === 'definitionName') {
|
||||
result.definitionName = item[key];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const setting = {
|
||||
value: item[key],
|
||||
errors: _.map(_.remove(validationFailures, (failure) => {
|
||||
|
||||
@@ -82,6 +82,9 @@ namespace NzbDrone.Common.Http.Dispatchers
|
||||
|
||||
if (httpWebResponse == null)
|
||||
{
|
||||
// Workaround for mono not closing connections properly in certain situations.
|
||||
AbortWebRequest(webRequest);
|
||||
|
||||
// The default messages for WebException on mono are pretty horrible.
|
||||
if (e.Status == WebExceptionStatus.NameResolutionFailure)
|
||||
{
|
||||
@@ -239,5 +242,36 @@ namespace NzbDrone.Common.Http.Dispatchers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for mono not closing connections properly on timeouts
|
||||
private void AbortWebRequest(HttpWebRequest webRequest)
|
||||
{
|
||||
// First affected version was mono 5.16
|
||||
if (OsInfo.IsNotWindows && _platformInfo.Version >= new Version(5, 16))
|
||||
{
|
||||
try
|
||||
{
|
||||
var currentOperationInfo = webRequest.GetType().GetField("currentOperation", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var currentOperation = currentOperationInfo.GetValue(webRequest);
|
||||
|
||||
if (currentOperation != null)
|
||||
{
|
||||
var responseStreamInfo = currentOperation.GetType().GetField("responseStream", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var responseStream = responseStreamInfo.GetValue(currentOperation) as Stream;
|
||||
|
||||
// Note that responseStream will likely be null once mono fixes it.
|
||||
responseStream?.Dispose();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// This can fail randomly on future mono versions that have been changed/fixed. Log to sentry and ignore.
|
||||
_logger.Trace()
|
||||
.Exception(ex)
|
||||
.Message("Unable to dispose responseStream on mono {0}", _platformInfo.Version)
|
||||
.Write();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Cache;
|
||||
@@ -88,11 +87,13 @@ namespace NzbDrone.Common.Http
|
||||
// 302 or 303 should default to GET on redirect even if POST on original
|
||||
if (response.StatusCode == HttpStatusCode.Redirect || response.StatusCode == HttpStatusCode.RedirectMethod)
|
||||
{
|
||||
request.Method = HttpMethod.Get;
|
||||
request.Method = HttpMethod.GET;
|
||||
request.ContentData = null;
|
||||
}
|
||||
|
||||
response = await ExecuteRequestAsync(request, cookieContainer);
|
||||
var redirectContainer = HandleRedirectCookies(request, response);
|
||||
|
||||
response = await ExecuteRequestAsync(request, redirectContainer);
|
||||
}
|
||||
while (response.HasHttpRedirect);
|
||||
}
|
||||
@@ -163,6 +164,41 @@ namespace NzbDrone.Common.Http
|
||||
return response;
|
||||
}
|
||||
|
||||
private CookieContainer HandleRedirectCookies(HttpRequest request, HttpResponse response)
|
||||
{
|
||||
var sourceContainer = new CookieContainer();
|
||||
|
||||
var responseCookies = response.GetCookies();
|
||||
|
||||
if (responseCookies.Count != 0)
|
||||
{
|
||||
foreach (var pair in responseCookies)
|
||||
{
|
||||
Cookie cookie;
|
||||
if (pair.Value == null)
|
||||
{
|
||||
cookie = new Cookie(pair.Key, "", "/")
|
||||
{
|
||||
Expires = DateTime.Now.AddDays(-1)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
cookie = new Cookie(pair.Key, pair.Value, "/")
|
||||
{
|
||||
// Use Now rather than UtcNow to work around Mono cookie expiry bug.
|
||||
// See https://gist.github.com/ta264/7822b1424f72e5b4c961
|
||||
Expires = DateTime.Now.AddHours(1)
|
||||
};
|
||||
}
|
||||
|
||||
sourceContainer.Add((Uri)request.Url, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
return sourceContainer;
|
||||
}
|
||||
|
||||
private CookieContainer InitializeRequestCookies(HttpRequest request)
|
||||
{
|
||||
lock (_cookieContainerCache)
|
||||
@@ -264,7 +300,7 @@ namespace NzbDrone.Common.Http
|
||||
|
||||
public Task<HttpResponse> GetAsync(HttpRequest request)
|
||||
{
|
||||
request.Method = HttpMethod.Get;
|
||||
request.Method = HttpMethod.GET;
|
||||
return ExecuteAsync(request);
|
||||
}
|
||||
|
||||
@@ -289,7 +325,7 @@ namespace NzbDrone.Common.Http
|
||||
|
||||
public Task<HttpResponse> HeadAsync(HttpRequest request)
|
||||
{
|
||||
request.Method = HttpMethod.Head;
|
||||
request.Method = HttpMethod.HEAD;
|
||||
return ExecuteAsync(request);
|
||||
}
|
||||
|
||||
@@ -300,7 +336,7 @@ namespace NzbDrone.Common.Http
|
||||
|
||||
public Task<HttpResponse> PostAsync(HttpRequest request)
|
||||
{
|
||||
request.Method = HttpMethod.Post;
|
||||
request.Method = HttpMethod.POST;
|
||||
return ExecuteAsync(request);
|
||||
}
|
||||
|
||||
|
||||
14
src/NzbDrone.Common/Http/HttpMethod.cs
Normal file
14
src/NzbDrone.Common/Http/HttpMethod.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public enum HttpMethod
|
||||
{
|
||||
GET,
|
||||
POST,
|
||||
PUT,
|
||||
DELETE,
|
||||
HEAD,
|
||||
OPTIONS,
|
||||
PATCH,
|
||||
MERGE
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
@@ -14,7 +13,6 @@ namespace NzbDrone.Common.Http
|
||||
{
|
||||
Url = new HttpUri(url);
|
||||
Headers = new HttpHeader();
|
||||
Method = HttpMethod.Get;
|
||||
ConnectionKeepAlive = true;
|
||||
AllowAutoRedirect = true;
|
||||
Cookies = new Dictionary<string, string>();
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using NzbDrone.Common.Extensions;
|
||||
|
||||
@@ -38,7 +37,7 @@ namespace NzbDrone.Common.Http
|
||||
{
|
||||
BaseUrl = new HttpUri(baseUrl);
|
||||
ResourceUrl = string.Empty;
|
||||
Method = HttpMethod.Get;
|
||||
Method = HttpMethod.GET;
|
||||
Encoding = Encoding.UTF8;
|
||||
QueryParams = new List<KeyValuePair<string, string>>();
|
||||
SuffixQueryParams = new List<KeyValuePair<string, string>>();
|
||||
@@ -276,7 +275,7 @@ namespace NzbDrone.Common.Http
|
||||
|
||||
public virtual HttpRequestBuilder Post()
|
||||
{
|
||||
Method = HttpMethod.Post;
|
||||
Method = HttpMethod.POST;
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -398,7 +397,7 @@ namespace NzbDrone.Common.Http
|
||||
|
||||
public virtual HttpRequestBuilder AddFormParameter(string key, object value)
|
||||
{
|
||||
if (Method != HttpMethod.Post)
|
||||
if (Method != HttpMethod.POST)
|
||||
{
|
||||
throw new NotSupportedException("HttpRequest Method must be POST to add FormParameter.");
|
||||
}
|
||||
@@ -414,7 +413,7 @@ namespace NzbDrone.Common.Http
|
||||
|
||||
public virtual HttpRequestBuilder AddFormUpload(string name, string fileName, byte[] data, string contentType = "application/octet-stream")
|
||||
{
|
||||
if (Method != HttpMethod.Post)
|
||||
if (Method != HttpMethod.POST)
|
||||
{
|
||||
throw new NotSupportedException("HttpRequest Method must be POST to add FormUpload.");
|
||||
}
|
||||
|
||||
@@ -11,21 +11,19 @@ namespace NzbDrone.Common.Http
|
||||
{
|
||||
private static readonly Regex RegexSetCookie = new Regex("^(.*?)=(.*?)(?:;|$)", RegexOptions.Compiled);
|
||||
|
||||
public HttpResponse(HttpRequest request, HttpHeader headers, CookieCollection cookies, byte[] binaryData, long elapsedTime = 0, HttpStatusCode statusCode = HttpStatusCode.OK)
|
||||
public HttpResponse(HttpRequest request, HttpHeader headers, byte[] binaryData, long elapsedTime = 0, HttpStatusCode statusCode = HttpStatusCode.OK)
|
||||
{
|
||||
Request = request;
|
||||
Headers = headers;
|
||||
Cookies = cookies;
|
||||
ResponseData = binaryData;
|
||||
StatusCode = statusCode;
|
||||
ElapsedTime = elapsedTime;
|
||||
}
|
||||
|
||||
public HttpResponse(HttpRequest request, HttpHeader headers, CookieCollection cookies, string content, long elapsedTime = 0, HttpStatusCode statusCode = HttpStatusCode.OK)
|
||||
public HttpResponse(HttpRequest request, HttpHeader headers, string content, long elapsedTime = 0, HttpStatusCode statusCode = HttpStatusCode.OK)
|
||||
{
|
||||
Request = request;
|
||||
Headers = headers;
|
||||
Cookies = cookies;
|
||||
ResponseData = Headers.GetEncodingFromContentType().GetBytes(content);
|
||||
_content = content;
|
||||
StatusCode = statusCode;
|
||||
@@ -34,7 +32,6 @@ namespace NzbDrone.Common.Http
|
||||
|
||||
public HttpRequest Request { get; private set; }
|
||||
public HttpHeader Headers { get; private set; }
|
||||
public CookieCollection Cookies { get; private set; }
|
||||
public HttpStatusCode StatusCode { get; private set; }
|
||||
public long ElapsedTime { get; private set; }
|
||||
public byte[] ResponseData { get; private set; }
|
||||
@@ -92,9 +89,14 @@ namespace NzbDrone.Common.Http
|
||||
{
|
||||
var result = new Dictionary<string, string>();
|
||||
|
||||
foreach (Cookie cookie in Cookies)
|
||||
var setCookieHeaders = CookieUtil.CookieHeaderToDictionary();
|
||||
foreach (var cookie in setCookieHeaders)
|
||||
{
|
||||
result[cookie.Name] = cookie.Value;
|
||||
var match = RegexSetCookie.Match(cookie);
|
||||
if (match.Success)
|
||||
{
|
||||
result[match.Groups[1].Value] = match.Groups[2].Value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using Newtonsoft.Json;
|
||||
using NzbDrone.Common.Serializer;
|
||||
|
||||
@@ -18,14 +17,14 @@ namespace NzbDrone.Common.Http
|
||||
public JsonRpcRequestBuilder(string baseUrl)
|
||||
: base(baseUrl)
|
||||
{
|
||||
Method = HttpMethod.Post;
|
||||
Method = HttpMethod.POST;
|
||||
JsonParameters = new List<object>();
|
||||
}
|
||||
|
||||
public JsonRpcRequestBuilder(string baseUrl, string method, IEnumerable<object> parameters)
|
||||
: base(baseUrl)
|
||||
{
|
||||
Method = HttpMethod.Post;
|
||||
Method = HttpMethod.POST;
|
||||
JsonMethod = method;
|
||||
JsonParameters = parameters.ToList();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -35,7 +34,7 @@ namespace NzbDrone.Core.Test.IndexerTests.AvistazTests
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Avistaz/recentfeed.json");
|
||||
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader { { "Content-Type", "application/json" } }, new CookieCollection(), recentFeed)));
|
||||
|
||||
var releases = (await Subject.Fetch(new MovieSearchCriteria { Categories = new int[] { 2000 } })).Releases;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -35,7 +34,7 @@ namespace NzbDrone.Core.Test.IndexerTests.AvistazTests
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/PrivateHD/recentfeed.json");
|
||||
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader { { "Content-Type", "application/json" } }, new CookieCollection(), recentFeed)));
|
||||
|
||||
var releases = (await Subject.Fetch(new MovieSearchCriteria { Categories = new int[] { 2000 } })).Releases;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -34,7 +33,7 @@ namespace NzbDrone.Core.Test.IndexerTests.FileListTests
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/FileList/recentfeed.json");
|
||||
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader(), new CookieCollection(), recentFeed)));
|
||||
|
||||
var releases = (await Subject.Fetch(new MovieSearchCriteria { Categories = new int[] { 2000 } })).Releases;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
@@ -46,7 +45,7 @@ namespace NzbDrone.Core.Test.IndexerTests.HDBitsTests
|
||||
var responseJson = ReadAllText(fileName);
|
||||
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Post), Subject.Definition))
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.POST), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader(), new CookieCollection(), responseJson)));
|
||||
|
||||
var torrents = (await Subject.Fetch(_movieSearchCriteria)).Releases;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -44,7 +43,7 @@ namespace NzbDrone.Core.Test.IndexerTests.NewznabTests
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Newznab/newznab_nzb_su.xml");
|
||||
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader(), new CookieCollection(), recentFeed)));
|
||||
|
||||
var releases = (await Subject.Fetch(new MovieSearchCriteria { Categories = new int[] { 2000 }, Limit = 100, Offset = 0 })).Releases;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -38,11 +37,11 @@ namespace NzbDrone.Core.Test.IndexerTests.PTPTests
|
||||
var responseJson = ReadAllText(fileName);
|
||||
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Post), Subject.Definition))
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.POST), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader(), new CookieCollection(), authStream.ToString())));
|
||||
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader { ContentType = HttpAccept.Json.Value }, new CookieCollection(), responseJson)));
|
||||
|
||||
var torrents = (await Subject.Fetch(new MovieSearchCriteria())).Releases;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -40,7 +39,7 @@ namespace NzbDrone.Core.Test.IndexerTests.RarbgTests
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Rarbg/RecentFeed_v2.json");
|
||||
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader(), new CookieCollection(), recentFeed)));
|
||||
|
||||
var releases = (await Subject.Fetch(new MovieSearchCriteria { Categories = new int[] { 2000 } })).Releases;
|
||||
@@ -67,7 +66,7 @@ namespace NzbDrone.Core.Test.IndexerTests.RarbgTests
|
||||
public async Task should_parse_error_20_as_empty_results()
|
||||
{
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader(), new CookieCollection(), "{ error_code: 20, error: \"some message\" }")));
|
||||
|
||||
var releases = (await Subject.Fetch(new MovieSearchCriteria { Categories = new int[] { 2000 } })).Releases;
|
||||
@@ -79,7 +78,7 @@ namespace NzbDrone.Core.Test.IndexerTests.RarbgTests
|
||||
public async Task should_warn_on_unknown_error()
|
||||
{
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader(), new CookieCollection(), "{ error_code: 25, error: \"some message\" }")));
|
||||
|
||||
var releases = (await Subject.Fetch(new MovieSearchCriteria { Categories = new int[] { 2000 } })).Releases;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -45,7 +44,7 @@ namespace NzbDrone.Core.Test.IndexerTests.TorznabTests
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Torznab/torznab_hdaccess_net.xml");
|
||||
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader(), new CookieCollection(), recentFeed)));
|
||||
|
||||
var releases = (await Subject.Fetch(new MovieSearchCriteria())).Releases;
|
||||
@@ -74,7 +73,7 @@ namespace NzbDrone.Core.Test.IndexerTests.TorznabTests
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Torznab/torznab_tpb.xml");
|
||||
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader(), new CookieCollection(), recentFeed)));
|
||||
|
||||
var releases = (await Subject.Fetch(new MovieSearchCriteria())).Releases;
|
||||
@@ -104,7 +103,7 @@ namespace NzbDrone.Core.Test.IndexerTests.TorznabTests
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/Torznab/torznab_animetosho.xml");
|
||||
|
||||
Mocker.GetMock<IIndexerHttpClient>()
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
|
||||
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET), Subject.Definition))
|
||||
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader(), new CookieCollection(), recentFeed)));
|
||||
|
||||
var releases = (await Subject.Fetch(new MovieSearchCriteria())).Releases;
|
||||
|
||||
@@ -30,27 +30,9 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
[TestCase("1", 1)]
|
||||
[TestCase("11", 11)]
|
||||
[TestCase("1000 grabs", 1000)]
|
||||
[TestCase("2.222", 2222)]
|
||||
[TestCase("2,222", 2222)]
|
||||
[TestCase("2 222", 2222)]
|
||||
[TestCase("2,22", 222)]
|
||||
public void should_parse_int_from_string(string original, int parsedInt)
|
||||
{
|
||||
ParseUtil.CoerceInt(original).Should().Be(parsedInt);
|
||||
}
|
||||
|
||||
[TestCase("1.0", 1.0)]
|
||||
[TestCase("1.1", 1.1)]
|
||||
[TestCase("1000 grabs", 1000.0)]
|
||||
[TestCase("2.222", 2.222)]
|
||||
[TestCase("2,222", 2.222)]
|
||||
[TestCase("2.222,22", 2222.22)]
|
||||
[TestCase("2,222.22", 2222.22)]
|
||||
[TestCase("2 222", 2222.0)]
|
||||
[TestCase("2,22", 2.22)]
|
||||
public void should_parse_double_from_string(string original, double parsedInt)
|
||||
{
|
||||
ParseUtil.CoerceDouble(original).Should().Be(parsedInt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using FluentValidation.Results;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
@@ -32,13 +31,13 @@ namespace NzbDrone.Core.Applications.LazyLibrarian
|
||||
|
||||
public LazyLibrarianStatus GetStatus(LazyLibrarianSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api", "getVersion", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api", "getVersion", HttpMethod.GET);
|
||||
return Execute<LazyLibrarianStatus>(request);
|
||||
}
|
||||
|
||||
public List<LazyLibrarianIndexer> GetIndexers(LazyLibrarianSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api", "listNabProviders", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api", "listNabProviders", HttpMethod.GET);
|
||||
|
||||
var response = Execute<LazyLibrarianIndexerResponse>(request);
|
||||
|
||||
@@ -77,7 +76,7 @@ namespace NzbDrone.Core.Applications.LazyLibrarian
|
||||
{ "providertype", indexerType.ToString().ToLower() }
|
||||
};
|
||||
|
||||
var request = BuildRequest(settings, "/api", "delProvider", HttpMethod.Get, parameters);
|
||||
var request = BuildRequest(settings, "/api", "delProvider", HttpMethod.GET, parameters);
|
||||
CheckForError(Execute<LazyLibrarianStatus>(request));
|
||||
}
|
||||
|
||||
@@ -93,7 +92,7 @@ namespace NzbDrone.Core.Applications.LazyLibrarian
|
||||
{ "categories", indexer.Categories }
|
||||
};
|
||||
|
||||
var request = BuildRequest(settings, "/api", "addProvider", HttpMethod.Get, parameters);
|
||||
var request = BuildRequest(settings, "/api", "addProvider", HttpMethod.GET, parameters);
|
||||
CheckForError(Execute<LazyLibrarianStatus>(request));
|
||||
return indexer;
|
||||
}
|
||||
@@ -111,7 +110,7 @@ namespace NzbDrone.Core.Applications.LazyLibrarian
|
||||
{ "altername", indexer.Altername }
|
||||
};
|
||||
|
||||
var request = BuildRequest(settings, "/api", "changeProvider", HttpMethod.Get, parameters);
|
||||
var request = BuildRequest(settings, "/api", "changeProvider", HttpMethod.GET, parameters);
|
||||
CheckForError(Execute<LazyLibrarianStatus>(request));
|
||||
return indexer;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using FluentValidation.Results;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
@@ -34,13 +33,13 @@ namespace NzbDrone.Core.Applications.Lidarr
|
||||
|
||||
public LidarrStatus GetStatus(LidarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v1/system/status", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api/v1/system/status", HttpMethod.GET);
|
||||
return Execute<LidarrStatus>(request);
|
||||
}
|
||||
|
||||
public List<LidarrIndexer> GetIndexers(LidarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v1/indexer", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api/v1/indexer", HttpMethod.GET);
|
||||
return Execute<List<LidarrIndexer>>(request);
|
||||
}
|
||||
|
||||
@@ -48,7 +47,7 @@ namespace NzbDrone.Core.Applications.Lidarr
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.GET);
|
||||
return Execute<LidarrIndexer>(request);
|
||||
}
|
||||
catch (HttpException ex)
|
||||
@@ -64,19 +63,19 @@ namespace NzbDrone.Core.Applications.Lidarr
|
||||
|
||||
public void RemoveIndexer(int indexerId, LidarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.Delete);
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.DELETE);
|
||||
_httpClient.Execute(request);
|
||||
}
|
||||
|
||||
public List<LidarrIndexer> GetIndexerSchema(LidarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v1/indexer/schema", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api/v1/indexer/schema", HttpMethod.GET);
|
||||
return Execute<List<LidarrIndexer>>(request);
|
||||
}
|
||||
|
||||
public LidarrIndexer AddIndexer(LidarrIndexer indexer, LidarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v1/indexer", HttpMethod.Post);
|
||||
var request = BuildRequest(settings, "/api/v1/indexer", HttpMethod.POST);
|
||||
|
||||
request.SetContent(indexer.ToJson());
|
||||
|
||||
@@ -85,7 +84,7 @@ namespace NzbDrone.Core.Applications.Lidarr
|
||||
|
||||
public LidarrIndexer UpdateIndexer(LidarrIndexer indexer, LidarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/{indexer.Id}", HttpMethod.Put);
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/{indexer.Id}", HttpMethod.PUT);
|
||||
|
||||
request.SetContent(indexer.ToJson());
|
||||
|
||||
@@ -94,7 +93,7 @@ namespace NzbDrone.Core.Applications.Lidarr
|
||||
|
||||
public ValidationFailure TestConnection(LidarrIndexer indexer, LidarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/test", HttpMethod.Post);
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/test", HttpMethod.POST);
|
||||
|
||||
request.SetContent(indexer.ToJson());
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using FluentValidation.Results;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
@@ -32,13 +31,13 @@ namespace NzbDrone.Core.Applications.Mylar
|
||||
|
||||
public MylarStatus GetStatus(MylarSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api", "getVersion", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api", "getVersion", HttpMethod.GET);
|
||||
return Execute<MylarStatus>(request);
|
||||
}
|
||||
|
||||
public List<MylarIndexer> GetIndexers(MylarSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api", "listProviders", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api", "listProviders", HttpMethod.GET);
|
||||
|
||||
var response = Execute<MylarIndexerResponse>(request);
|
||||
|
||||
@@ -77,7 +76,7 @@ namespace NzbDrone.Core.Applications.Mylar
|
||||
{ "providertype", indexerType.ToString().ToLower() }
|
||||
};
|
||||
|
||||
var request = BuildRequest(settings, "/api", "delProvider", HttpMethod.Get, parameters);
|
||||
var request = BuildRequest(settings, "/api", "delProvider", HttpMethod.GET, parameters);
|
||||
CheckForError(Execute<MylarStatus>(request));
|
||||
}
|
||||
|
||||
@@ -93,7 +92,7 @@ namespace NzbDrone.Core.Applications.Mylar
|
||||
{ "categories", indexer.Categories }
|
||||
};
|
||||
|
||||
var request = BuildRequest(settings, "/api", "addProvider", HttpMethod.Get, parameters);
|
||||
var request = BuildRequest(settings, "/api", "addProvider", HttpMethod.GET, parameters);
|
||||
CheckForError(Execute<MylarStatus>(request));
|
||||
return indexer;
|
||||
}
|
||||
@@ -111,7 +110,7 @@ namespace NzbDrone.Core.Applications.Mylar
|
||||
{ "altername", indexer.Altername }
|
||||
};
|
||||
|
||||
var request = BuildRequest(settings, "/api", "changeProvider", HttpMethod.Get, parameters);
|
||||
var request = BuildRequest(settings, "/api", "changeProvider", HttpMethod.GET, parameters);
|
||||
CheckForError(Execute<MylarStatus>(request));
|
||||
return indexer;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using FluentValidation.Results;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
@@ -34,13 +33,13 @@ namespace NzbDrone.Core.Applications.Radarr
|
||||
|
||||
public RadarrStatus GetStatus(RadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v3/system/status", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api/v3/system/status", HttpMethod.GET);
|
||||
return Execute<RadarrStatus>(request);
|
||||
}
|
||||
|
||||
public List<RadarrIndexer> GetIndexers(RadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v3/indexer", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api/v3/indexer", HttpMethod.GET);
|
||||
return Execute<List<RadarrIndexer>>(request);
|
||||
}
|
||||
|
||||
@@ -48,7 +47,7 @@ namespace NzbDrone.Core.Applications.Radarr
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.GET);
|
||||
return Execute<RadarrIndexer>(request);
|
||||
}
|
||||
catch (HttpException ex)
|
||||
@@ -64,19 +63,19 @@ namespace NzbDrone.Core.Applications.Radarr
|
||||
|
||||
public void RemoveIndexer(int indexerId, RadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.Delete);
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.DELETE);
|
||||
_httpClient.Execute(request);
|
||||
}
|
||||
|
||||
public List<RadarrIndexer> GetIndexerSchema(RadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v3/indexer/schema", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api/v3/indexer/schema", HttpMethod.GET);
|
||||
return Execute<List<RadarrIndexer>>(request);
|
||||
}
|
||||
|
||||
public RadarrIndexer AddIndexer(RadarrIndexer indexer, RadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v3/indexer", HttpMethod.Post);
|
||||
var request = BuildRequest(settings, "/api/v3/indexer", HttpMethod.POST);
|
||||
|
||||
request.SetContent(indexer.ToJson());
|
||||
|
||||
@@ -85,7 +84,7 @@ namespace NzbDrone.Core.Applications.Radarr
|
||||
|
||||
public RadarrIndexer UpdateIndexer(RadarrIndexer indexer, RadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/{indexer.Id}", HttpMethod.Put);
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/{indexer.Id}", HttpMethod.PUT);
|
||||
|
||||
request.SetContent(indexer.ToJson());
|
||||
|
||||
@@ -94,7 +93,7 @@ namespace NzbDrone.Core.Applications.Radarr
|
||||
|
||||
public ValidationFailure TestConnection(RadarrIndexer indexer, RadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/test", HttpMethod.Post);
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/test", HttpMethod.POST);
|
||||
|
||||
request.SetContent(indexer.ToJson());
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using FluentValidation.Results;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
@@ -34,13 +33,13 @@ namespace NzbDrone.Core.Applications.Readarr
|
||||
|
||||
public ReadarrStatus GetStatus(ReadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v1/system/status", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api/v1/system/status", HttpMethod.GET);
|
||||
return Execute<ReadarrStatus>(request);
|
||||
}
|
||||
|
||||
public List<ReadarrIndexer> GetIndexers(ReadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v1/indexer", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api/v1/indexer", HttpMethod.GET);
|
||||
return Execute<List<ReadarrIndexer>>(request);
|
||||
}
|
||||
|
||||
@@ -48,7 +47,7 @@ namespace NzbDrone.Core.Applications.Readarr
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.GET);
|
||||
return Execute<ReadarrIndexer>(request);
|
||||
}
|
||||
catch (HttpException ex)
|
||||
@@ -64,19 +63,19 @@ namespace NzbDrone.Core.Applications.Readarr
|
||||
|
||||
public void RemoveIndexer(int indexerId, ReadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.Delete);
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/{indexerId}", HttpMethod.DELETE);
|
||||
_httpClient.Execute(request);
|
||||
}
|
||||
|
||||
public List<ReadarrIndexer> GetIndexerSchema(ReadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v1/indexer/schema", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api/v1/indexer/schema", HttpMethod.GET);
|
||||
return Execute<List<ReadarrIndexer>>(request);
|
||||
}
|
||||
|
||||
public ReadarrIndexer AddIndexer(ReadarrIndexer indexer, ReadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v1/indexer", HttpMethod.Post);
|
||||
var request = BuildRequest(settings, "/api/v1/indexer", HttpMethod.POST);
|
||||
|
||||
request.SetContent(indexer.ToJson());
|
||||
|
||||
@@ -85,7 +84,7 @@ namespace NzbDrone.Core.Applications.Readarr
|
||||
|
||||
public ReadarrIndexer UpdateIndexer(ReadarrIndexer indexer, ReadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/{indexer.Id}", HttpMethod.Put);
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/{indexer.Id}", HttpMethod.PUT);
|
||||
|
||||
request.SetContent(indexer.ToJson());
|
||||
|
||||
@@ -94,7 +93,7 @@ namespace NzbDrone.Core.Applications.Readarr
|
||||
|
||||
public ValidationFailure TestConnection(ReadarrIndexer indexer, ReadarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/test", HttpMethod.Post);
|
||||
var request = BuildRequest(settings, $"/api/v1/indexer/test", HttpMethod.POST);
|
||||
|
||||
request.SetContent(indexer.ToJson());
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using FluentValidation.Results;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
@@ -34,13 +33,13 @@ namespace NzbDrone.Core.Applications.Sonarr
|
||||
|
||||
public SonarrStatus GetStatus(SonarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v3/system/status", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api/v3/system/status", HttpMethod.GET);
|
||||
return Execute<SonarrStatus>(request);
|
||||
}
|
||||
|
||||
public List<SonarrIndexer> GetIndexers(SonarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v3/indexer", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api/v3/indexer", HttpMethod.GET);
|
||||
return Execute<List<SonarrIndexer>>(request);
|
||||
}
|
||||
|
||||
@@ -48,7 +47,7 @@ namespace NzbDrone.Core.Applications.Sonarr
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.GET);
|
||||
return Execute<SonarrIndexer>(request);
|
||||
}
|
||||
catch (HttpException ex)
|
||||
@@ -64,19 +63,19 @@ namespace NzbDrone.Core.Applications.Sonarr
|
||||
|
||||
public void RemoveIndexer(int indexerId, SonarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.Delete);
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/{indexerId}", HttpMethod.DELETE);
|
||||
_httpClient.Execute(request);
|
||||
}
|
||||
|
||||
public List<SonarrIndexer> GetIndexerSchema(SonarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v3/indexer/schema", HttpMethod.Get);
|
||||
var request = BuildRequest(settings, "/api/v3/indexer/schema", HttpMethod.GET);
|
||||
return Execute<List<SonarrIndexer>>(request);
|
||||
}
|
||||
|
||||
public SonarrIndexer AddIndexer(SonarrIndexer indexer, SonarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, "/api/v3/indexer", HttpMethod.Post);
|
||||
var request = BuildRequest(settings, "/api/v3/indexer", HttpMethod.POST);
|
||||
|
||||
request.SetContent(indexer.ToJson());
|
||||
|
||||
@@ -85,7 +84,7 @@ namespace NzbDrone.Core.Applications.Sonarr
|
||||
|
||||
public SonarrIndexer UpdateIndexer(SonarrIndexer indexer, SonarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/{indexer.Id}", HttpMethod.Put);
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/{indexer.Id}", HttpMethod.PUT);
|
||||
|
||||
request.SetContent(indexer.ToJson());
|
||||
|
||||
@@ -94,7 +93,7 @@ namespace NzbDrone.Core.Applications.Sonarr
|
||||
|
||||
public ValidationFailure TestConnection(SonarrIndexer indexer, SonarrSettings settings)
|
||||
{
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/test", HttpMethod.Post);
|
||||
var request = BuildRequest(settings, $"/api/v3/indexer/test", HttpMethod.POST);
|
||||
|
||||
request.SetContent(indexer.ToJson());
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ namespace NzbDrone.Core.Configuration
|
||||
public string PostgresPassword => GetValue("PostgresPassword", string.Empty, persist: false);
|
||||
public string PostgresMainDb => GetValue("PostgresMainDb", "prowlarr-main", persist: false);
|
||||
public string PostgresLogDb => GetValue("PostgresLogDb", "prowlarr-log", persist: false);
|
||||
public int PostgresPort => GetValueInt("PostgresPort", 5432, persist: false);
|
||||
public int PostgresPort => GetValueInt("PostgresPort", 5436, persist: false);
|
||||
public bool LogSql => GetValueBoolean("LogSql", false, persist: false);
|
||||
public int LogRotate => GetValueInt("LogRotate", 50, persist: false);
|
||||
public bool FilterSentryEvents => GetValueBoolean("FilterSentryEvents", true, persist: false);
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(15)]
|
||||
public class IndexerVersions : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Create.TableForModel("IndexerDefinitionVersions")
|
||||
.WithColumn("DefinitionId").AsString().NotNullable().Unique()
|
||||
.WithColumn("File").AsString().NotNullable().Unique()
|
||||
.WithColumn("Sha").AsString().Nullable()
|
||||
.WithColumn("LastUpdated").AsDateTime().Nullable();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@ using NzbDrone.Core.Datastore.Converters;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.IndexerProxies;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.IndexerVersions;
|
||||
using NzbDrone.Core.Instrumentation;
|
||||
using NzbDrone.Core.Jobs;
|
||||
using NzbDrone.Core.Languages;
|
||||
@@ -95,7 +94,6 @@ namespace NzbDrone.Core.Datastore
|
||||
Mapper.Entity<UpdateHistory>("UpdateHistory").RegisterModel();
|
||||
|
||||
Mapper.Entity<AppSyncProfile>("AppSyncProfiles").RegisterModel();
|
||||
Mapper.Entity<IndexerDefinitionVersion>("IndexerDefinitionVersions").RegisterModel();
|
||||
}
|
||||
|
||||
private static void RegisterMappers()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Common.Http;
|
||||
@@ -143,19 +142,15 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
|
||||
return authResponse.Data.SId;
|
||||
}
|
||||
|
||||
protected HttpRequestBuilder BuildRequest(DownloadStationSettings settings, string methodName, int apiVersion, HttpMethod httpVerb = null)
|
||||
protected HttpRequestBuilder BuildRequest(DownloadStationSettings settings, string methodName, int apiVersion, HttpMethod httpVerb = HttpMethod.GET)
|
||||
{
|
||||
httpVerb ??= HttpMethod.Get;
|
||||
|
||||
var info = GetApiInfo(_apiType, settings);
|
||||
|
||||
return BuildRequest(settings, info, methodName, apiVersion, httpVerb);
|
||||
}
|
||||
|
||||
private HttpRequestBuilder BuildRequest(DownloadStationSettings settings, DiskStationApiInfo apiInfo, string methodName, int apiVersion, HttpMethod httpVerb = null)
|
||||
private HttpRequestBuilder BuildRequest(DownloadStationSettings settings, DiskStationApiInfo apiInfo, string methodName, int apiVersion, HttpMethod httpVerb = HttpMethod.GET)
|
||||
{
|
||||
httpVerb ??= HttpMethod.Get;
|
||||
|
||||
var requestBuilder = new HttpRequestBuilder(settings.UseSsl, settings.Host, settings.Port).Resource($"webapi/{apiInfo.Path}");
|
||||
requestBuilder.Method = httpVerb;
|
||||
requestBuilder.LogResponseContent = true;
|
||||
@@ -168,7 +163,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
|
||||
throw new ArgumentOutOfRangeException(nameof(apiVersion));
|
||||
}
|
||||
|
||||
if (httpVerb == HttpMethod.Post)
|
||||
if (httpVerb == HttpMethod.POST)
|
||||
{
|
||||
if (apiInfo.NeedsAuthentication)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Collections.Generic;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Common.Extensions;
|
||||
@@ -25,7 +24,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation.Proxies
|
||||
|
||||
public void AddTaskFromData(byte[] data, string filename, string downloadDirectory, DownloadStationSettings settings)
|
||||
{
|
||||
var requestBuilder = BuildRequest(settings, "create", 2, HttpMethod.Post);
|
||||
var requestBuilder = BuildRequest(settings, "create", 2, HttpMethod.POST);
|
||||
|
||||
if (downloadDirectory.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Common.Http;
|
||||
@@ -108,7 +107,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
|
||||
{
|
||||
var verifyRequest = BuildRequest(settings).Resource("/auth/verify").Build();
|
||||
|
||||
verifyRequest.Method = HttpMethod.Get;
|
||||
verifyRequest.Method = HttpMethod.GET;
|
||||
|
||||
HandleRequest(verifyRequest, settings);
|
||||
}
|
||||
@@ -181,7 +180,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
|
||||
{
|
||||
var getTorrentsRequest = BuildRequest(settings).Resource("/torrents").Build();
|
||||
|
||||
getTorrentsRequest.Method = HttpMethod.Get;
|
||||
getTorrentsRequest.Method = HttpMethod.GET;
|
||||
|
||||
return Json.Deserialize<TorrentListSummary>(HandleRequest(getTorrentsRequest, settings).Content).Torrents;
|
||||
}
|
||||
@@ -190,7 +189,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
|
||||
{
|
||||
var contentsRequest = BuildRequest(settings).Resource($"/torrents/{hash}/contents").Build();
|
||||
|
||||
contentsRequest.Method = HttpMethod.Get;
|
||||
contentsRequest.Method = HttpMethod.GET;
|
||||
|
||||
return Json.Deserialize<List<TorrentContent>>(HandleRequest(contentsRequest, settings).Content).ConvertAll(content => content.Path);
|
||||
}
|
||||
@@ -199,7 +198,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
|
||||
{
|
||||
var tagsRequest = BuildRequest(settings).Resource("/torrents/tags").Build();
|
||||
|
||||
tagsRequest.Method = HttpMethod.Patch;
|
||||
tagsRequest.Method = HttpMethod.PATCH;
|
||||
|
||||
var body = new Dictionary<string, object>
|
||||
{
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
[FieldDefinition(8, Label = "Priority", Type = FieldType.Select, SelectOptions = typeof(RTorrentPriority), HelpText = "Priority to use when grabbing items")]
|
||||
public int Priority { get; set; }
|
||||
|
||||
[FieldDefinition(9, Label = "Add Stopped", Type = FieldType.Checkbox, HelpText = "Enabling will add torrents and magnets to ruTorrent in a stopped state")]
|
||||
[FieldDefinition(9, Label = "Add Stopped", Type = FieldType.Checkbox, HelpText = "Enabling will prevent magnets from downloading before downloading")]
|
||||
public bool AddStopped { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.Cardigann;
|
||||
using NzbDrone.Core.IndexerVersions;
|
||||
using NzbDrone.Core.Localization;
|
||||
using NzbDrone.Core.ThingiProvider.Events;
|
||||
|
||||
namespace NzbDrone.Core.HealthCheck.Checks
|
||||
{
|
||||
[CheckOn(typeof(ProviderDeletedEvent<IIndexer>))]
|
||||
public class NoDefinitionCheck : HealthCheckBase
|
||||
{
|
||||
private readonly IIndexerDefinitionUpdateService _indexerDefinitionUpdateService;
|
||||
private readonly IIndexerFactory _indexerFactory;
|
||||
|
||||
public NoDefinitionCheck(IIndexerDefinitionUpdateService indexerDefinitionUpdateService, IIndexerFactory indexerFactory, ILocalizationService localizationService)
|
||||
: base(localizationService)
|
||||
{
|
||||
_indexerDefinitionUpdateService = indexerDefinitionUpdateService;
|
||||
_indexerFactory = indexerFactory;
|
||||
}
|
||||
|
||||
public override HealthCheck Check()
|
||||
{
|
||||
var currentDefs = _indexerDefinitionUpdateService.All();
|
||||
|
||||
var noDefIndexers = _indexerFactory.AllProviders(false)
|
||||
.Where(i => i.Definition.Implementation == "Cardigann" && !currentDefs.Any(d => d.File == ((CardigannSettings)i.Definition.Settings).DefinitionFile)).ToList();
|
||||
|
||||
if (noDefIndexers.Count == 0)
|
||||
{
|
||||
return new HealthCheck(GetType());
|
||||
}
|
||||
|
||||
var healthType = HealthCheckResult.Error;
|
||||
var healthMessage = string.Format(_localizationService.GetLocalizedString("IndexerNoDefCheckMessage"),
|
||||
string.Join(", ", noDefIndexers.Select(v => v.Definition.Name)));
|
||||
|
||||
return new HealthCheck(GetType(),
|
||||
healthType,
|
||||
healthMessage,
|
||||
"#indexers-have-no-definition");
|
||||
}
|
||||
|
||||
public override bool CheckOnSchedule => false;
|
||||
}
|
||||
}
|
||||
@@ -35,13 +35,10 @@ namespace NzbDrone.Core.HealthCheck.Checks
|
||||
return new HealthCheck(GetType());
|
||||
}
|
||||
|
||||
var healthType = HealthCheckResult.Warning;
|
||||
var healthMessage = string.Format(_localizationService.GetLocalizedString("IndexerObsoleteCheckMessage"),
|
||||
string.Join(", ", oldIndexers.Select(v => v.Definition.Name)));
|
||||
|
||||
return new HealthCheck(GetType(),
|
||||
healthType,
|
||||
healthMessage,
|
||||
HealthCheckResult.Warning,
|
||||
string.Format(_localizationService.GetLocalizedString("IndexerObsoleteCheckMessage"),
|
||||
string.Join(", ", oldIndexers.Select(v => v.Definition.Name))),
|
||||
"#indexers-are-obsolete");
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using FluentValidation.Results;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
@@ -116,7 +115,7 @@ namespace NzbDrone.Core.IndexerProxies.FlareSolverr
|
||||
var userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36";
|
||||
var maxTimeout = Settings.RequestTimeout * 1000;
|
||||
|
||||
if (request.Method == HttpMethod.Get)
|
||||
if (request.Method == HttpMethod.GET)
|
||||
{
|
||||
req = new FlareSolverrRequestGet
|
||||
{
|
||||
@@ -126,7 +125,7 @@ namespace NzbDrone.Core.IndexerProxies.FlareSolverr
|
||||
UserAgent = userAgent
|
||||
};
|
||||
}
|
||||
else if (request.Method == HttpMethod.Post)
|
||||
else if (request.Method == HttpMethod.POST)
|
||||
{
|
||||
var contentTypeType = request.Headers.ContentType;
|
||||
|
||||
@@ -168,7 +167,7 @@ namespace NzbDrone.Core.IndexerProxies.FlareSolverr
|
||||
var newRequest = new HttpRequest(apiUrl, HttpAccept.Json);
|
||||
|
||||
newRequest.Headers.ContentType = "application/json";
|
||||
newRequest.Method = HttpMethod.Post;
|
||||
newRequest.Method = HttpMethod.POST;
|
||||
newRequest.SetContent(req.ToJson());
|
||||
|
||||
_logger.Debug("Applying FlareSolverr Proxy {0} to request {1}", Name, request.Url);
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||
|
||||
private async Task<List<ReleaseInfo>> Dispatch(Func<IIndexer, Task<IndexerPageableQueryResult>> searchAction, SearchCriteriaBase criteriaBase)
|
||||
{
|
||||
var indexers = _indexerFactory.Enabled();
|
||||
var indexers = _indexerFactory.GetAvailableProviders();
|
||||
|
||||
if (criteriaBase.IndexerIds != null && criteriaBase.IndexerIds.Count > 0)
|
||||
{
|
||||
|
||||
@@ -6,11 +6,10 @@ using NLog;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Indexers.Cardigann;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
|
||||
@@ -19,18 +18,15 @@ namespace NzbDrone.Core.IndexerVersions
|
||||
public interface IIndexerDefinitionUpdateService
|
||||
{
|
||||
List<CardigannMetaDefinition> All();
|
||||
CardigannDefinition GetCachedDefinition(string fileKey);
|
||||
CardigannDefinition GetDefinition(string fileKey);
|
||||
List<string> GetBlocklist();
|
||||
}
|
||||
|
||||
public class IndexerDefinitionUpdateService : IIndexerDefinitionUpdateService, IExecute<IndexerDefinitionUpdateCommand>, IHandle<ApplicationStartedEvent>
|
||||
public class IndexerDefinitionUpdateService : IIndexerDefinitionUpdateService, IExecute<IndexerDefinitionUpdateCommand>
|
||||
{
|
||||
/* Update Service will fall back if version # does not exist for an indexer per Ta */
|
||||
|
||||
private const string DEFINITION_BRANCH = "master";
|
||||
private const int DEFINITION_VERSION = 3;
|
||||
|
||||
//Used when moving yml to C#
|
||||
private readonly List<string> _defintionBlocklist = new List<string>()
|
||||
{
|
||||
"aither",
|
||||
@@ -53,7 +49,6 @@ namespace NzbDrone.Core.IndexerVersions
|
||||
private readonly IHttpClient _httpClient;
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IIndexerDefinitionVersionService _versionService;
|
||||
private readonly ICached<CardigannDefinition> _cache;
|
||||
private readonly Logger _logger;
|
||||
|
||||
@@ -65,13 +60,11 @@ namespace NzbDrone.Core.IndexerVersions
|
||||
public IndexerDefinitionUpdateService(IHttpClient httpClient,
|
||||
IAppFolderInfo appFolderInfo,
|
||||
IDiskProvider diskProvider,
|
||||
IIndexerDefinitionVersionService versionService,
|
||||
ICacheManager cacheManager,
|
||||
Logger logger)
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
_diskProvider = diskProvider;
|
||||
_versionService = versionService;
|
||||
_cache = cacheManager.GetCache<CardigannDefinition>(typeof(CardigannDefinition), "definitions");
|
||||
_httpClient = httpClient;
|
||||
_logger = logger;
|
||||
@@ -83,24 +76,43 @@ namespace NzbDrone.Core.IndexerVersions
|
||||
|
||||
try
|
||||
{
|
||||
// Grab latest def list from server or fallback to disk
|
||||
try
|
||||
var request = new HttpRequest($"https://indexers.prowlarr.com/master/{DEFINITION_VERSION}");
|
||||
var response = _httpClient.Get<List<CardigannMetaDefinition>>(request);
|
||||
indexerList = response.Resource.Where(i => !_defintionBlocklist.Contains(i.File)).ToList();
|
||||
|
||||
var definitionFolder = Path.Combine(_appFolderInfo.AppDataFolder, "Definitions", "Custom");
|
||||
|
||||
var directoryInfo = new DirectoryInfo(definitionFolder);
|
||||
|
||||
if (directoryInfo.Exists)
|
||||
{
|
||||
var request = new HttpRequest($"https://indexers.prowlarr.com/{DEFINITION_BRANCH}/{DEFINITION_VERSION}");
|
||||
var response = _httpClient.Get<List<CardigannMetaDefinition>>(request);
|
||||
indexerList = response.Resource.Where(i => !_defintionBlocklist.Contains(i.File)).ToList();
|
||||
var files = directoryInfo.GetFiles($"*.yml");
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
_logger.Debug("Loading Custom Cardigann definition " + file.FullName);
|
||||
|
||||
try
|
||||
{
|
||||
var definitionString = File.ReadAllText(file.FullName);
|
||||
var definition = _deserializer.Deserialize<CardigannMetaDefinition>(definitionString);
|
||||
|
||||
definition.File = Path.GetFileNameWithoutExtension(file.Name);
|
||||
|
||||
if (indexerList.Any(i => i.File == definition.File || i.Name == definition.Name))
|
||||
{
|
||||
_logger.Warn("Custom Cardigann definition {0} does not have unique file name or Indexer name", file.FullName);
|
||||
continue;
|
||||
}
|
||||
|
||||
indexerList.Add(definition);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error($"Error while parsing custom Cardigann definition {file.FullName}\n{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
var definitionFolder = Path.Combine(_appFolderInfo.AppDataFolder, "Definitions");
|
||||
|
||||
indexerList = ReadDefinitionsFromDisk(indexerList, definitionFolder);
|
||||
}
|
||||
|
||||
//Check for custom definitions
|
||||
var customDefinitionFolder = Path.Combine(_appFolderInfo.AppDataFolder, "Definitions", "Custom");
|
||||
|
||||
indexerList = ReadDefinitionsFromDisk(indexerList, customDefinitionFolder);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -110,14 +122,14 @@ namespace NzbDrone.Core.IndexerVersions
|
||||
return indexerList;
|
||||
}
|
||||
|
||||
public CardigannDefinition GetCachedDefinition(string fileKey)
|
||||
public CardigannDefinition GetDefinition(string file)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fileKey))
|
||||
if (string.IsNullOrEmpty(file))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(fileKey));
|
||||
throw new ArgumentNullException(nameof(file));
|
||||
}
|
||||
|
||||
var definition = _cache.Get(fileKey, () => GetUncachedDefinition(fileKey));
|
||||
var definition = _cache.Get(file, () => LoadIndexerDef(file));
|
||||
|
||||
return definition;
|
||||
}
|
||||
@@ -127,46 +139,15 @@ namespace NzbDrone.Core.IndexerVersions
|
||||
return _defintionBlocklist;
|
||||
}
|
||||
|
||||
private List<CardigannMetaDefinition> ReadDefinitionsFromDisk(List<CardigannMetaDefinition> defs, string path, SearchOption options = SearchOption.TopDirectoryOnly)
|
||||
private CardigannDefinition GetHttpDefinition(string id)
|
||||
{
|
||||
var indexerList = defs;
|
||||
|
||||
var directoryInfo = new DirectoryInfo(path);
|
||||
|
||||
if (directoryInfo.Exists)
|
||||
{
|
||||
var files = directoryInfo.GetFiles($"*.yml", options);
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
_logger.Debug("Loading definition " + file.FullName);
|
||||
|
||||
try
|
||||
{
|
||||
var definitionString = File.ReadAllText(file.FullName);
|
||||
var definition = _deserializer.Deserialize<CardigannMetaDefinition>(definitionString);
|
||||
|
||||
definition.File = Path.GetFileNameWithoutExtension(file.Name);
|
||||
|
||||
if (indexerList.Any(i => i.File == definition.File || i.Name == definition.Name))
|
||||
{
|
||||
_logger.Warn("Definition {0} does not have unique file name or Indexer name", file.FullName);
|
||||
continue;
|
||||
}
|
||||
|
||||
indexerList.Add(definition);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error($"Error while parsing Cardigann definition {file.FullName}\n{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return indexerList;
|
||||
var req = new HttpRequest($"https://indexers.prowlarr.com/master/{DEFINITION_VERSION}/{id}");
|
||||
var response = _httpClient.Get(req);
|
||||
var definition = _deserializer.Deserialize<CardigannDefinition>(response.Content);
|
||||
return CleanIndexerDefinition(definition);
|
||||
}
|
||||
|
||||
private CardigannDefinition GetUncachedDefinition(string fileKey)
|
||||
private CardigannDefinition LoadIndexerDef(string fileKey)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fileKey))
|
||||
{
|
||||
@@ -201,26 +182,9 @@ namespace NzbDrone.Core.IndexerVersions
|
||||
}
|
||||
}
|
||||
|
||||
var dbDefs = _versionService.All();
|
||||
|
||||
//Check to ensure it's in versioned defs before we go to web
|
||||
if (dbDefs.Count > 0 && dbDefs.Any(x => x.File == fileKey))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(fileKey));
|
||||
}
|
||||
|
||||
//No definition was returned locally, go to the web
|
||||
return GetHttpDefinition(fileKey);
|
||||
}
|
||||
|
||||
private CardigannDefinition GetHttpDefinition(string id)
|
||||
{
|
||||
var req = new HttpRequest($"https://indexers.prowlarr.com/{DEFINITION_BRANCH}/{DEFINITION_VERSION}/{id}");
|
||||
var response = _httpClient.Get(req);
|
||||
var definition = _deserializer.Deserialize<CardigannDefinition>(response.Content);
|
||||
return CleanIndexerDefinition(definition);
|
||||
}
|
||||
|
||||
private CardigannDefinition CleanIndexerDefinition(CardigannDefinition definition)
|
||||
{
|
||||
if (definition.Settings == null)
|
||||
@@ -260,12 +224,6 @@ namespace NzbDrone.Core.IndexerVersions
|
||||
return definition;
|
||||
}
|
||||
|
||||
public void Handle(ApplicationStartedEvent message)
|
||||
{
|
||||
// Sync indexers on app start
|
||||
UpdateLocalDefinitions();
|
||||
}
|
||||
|
||||
public void Execute(IndexerDefinitionUpdateCommand message)
|
||||
{
|
||||
UpdateLocalDefinitions();
|
||||
@@ -280,46 +238,29 @@ namespace NzbDrone.Core.IndexerVersions
|
||||
|
||||
private void UpdateLocalDefinitions()
|
||||
{
|
||||
var startupFolder = _appFolderInfo.AppDataFolder;
|
||||
|
||||
var request = new HttpRequest($"https://indexers.prowlarr.com/{DEFINITION_BRANCH}/{DEFINITION_VERSION}");
|
||||
var request = new HttpRequest($"https://indexers.prowlarr.com/master/{DEFINITION_VERSION}");
|
||||
var response = _httpClient.Get<List<CardigannMetaDefinition>>(request);
|
||||
|
||||
var currentDefs = _versionService.All().ToDictionary(x => x.DefinitionId, x => x.Sha);
|
||||
|
||||
try
|
||||
foreach (var def in response.Resource)
|
||||
{
|
||||
EnsureDefinitionsFolder();
|
||||
|
||||
foreach (var def in response.Resource)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var saveFile = Path.Combine(startupFolder, "Definitions", $"{def.File}.yml");
|
||||
var startupFolder = _appFolderInfo.AppDataFolder;
|
||||
|
||||
if (currentDefs.TryGetValue(def.Id, out var defSha) && defSha == def.Sha)
|
||||
{
|
||||
_logger.Trace("Indexer already up to date: {0}", def.File);
|
||||
EnsureDefinitionsFolder();
|
||||
|
||||
continue;
|
||||
}
|
||||
var saveFile = Path.Combine(startupFolder, "Definitions", $"{def.File}.yml");
|
||||
|
||||
_httpClient.DownloadFile($"https://indexers.prowlarr.com/{DEFINITION_BRANCH}/{DEFINITION_VERSION}/{def.File}", saveFile);
|
||||
_httpClient.DownloadFile($"https://indexers.prowlarr.com/master/{DEFINITION_VERSION}/{def.File}", saveFile);
|
||||
|
||||
_versionService.Upsert(new IndexerDefinitionVersion { Sha = def.Sha, DefinitionId = def.Id, File = def.File, LastUpdated = DateTime.UtcNow });
|
||||
_cache.Remove(def.File);
|
||||
|
||||
_cache.Remove(def.File);
|
||||
_logger.Debug("Updated definition: {0}", def.File);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error("Definition download failed: {0}, {1}", def.File, ex.Message);
|
||||
}
|
||||
_logger.Debug("Updated definition: {0}", def.File);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error("Definition download failed: {0}, {1}", def.File, ex.Message);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error(ex, "Definition download failed, error creating definitions folder in {0}", startupFolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
using System;
|
||||
using NzbDrone.Core.Datastore;
|
||||
|
||||
namespace NzbDrone.Core.IndexerVersions
|
||||
{
|
||||
public class IndexerDefinitionVersion : ModelBase
|
||||
{
|
||||
public string File { get; set; }
|
||||
public string Sha { get; set; }
|
||||
public DateTime LastUpdated { get; set; }
|
||||
public string DefinitionId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
||||
namespace NzbDrone.Core.IndexerVersions
|
||||
{
|
||||
public interface IIndexerDefinitionVersionRepository : IBasicRepository<IndexerDefinitionVersion>
|
||||
{
|
||||
public IndexerDefinitionVersion GetByDefId(string defId);
|
||||
}
|
||||
|
||||
public class IndexerDefinitionVersionRepository : BasicRepository<IndexerDefinitionVersion>, IIndexerDefinitionVersionRepository
|
||||
{
|
||||
public IndexerDefinitionVersionRepository(IMainDatabase database, IEventAggregator eventAggregator)
|
||||
: base(database, eventAggregator)
|
||||
{
|
||||
}
|
||||
|
||||
public IndexerDefinitionVersion GetByDefId(string defId)
|
||||
{
|
||||
return Query(x => x.DefinitionId == defId).SingleOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Core.IndexerVersions
|
||||
{
|
||||
public interface IIndexerDefinitionVersionService
|
||||
{
|
||||
IndexerDefinitionVersion Get(int indexerVersionId);
|
||||
IndexerDefinitionVersion GetByDefId(string defId);
|
||||
List<IndexerDefinitionVersion> All();
|
||||
IndexerDefinitionVersion Add(IndexerDefinitionVersion defVersion);
|
||||
IndexerDefinitionVersion Upsert(IndexerDefinitionVersion defVersion);
|
||||
void Delete(int indexerVersionId);
|
||||
}
|
||||
|
||||
public class IndexerDefinitionVersionService : IIndexerDefinitionVersionService
|
||||
{
|
||||
private readonly IIndexerDefinitionVersionRepository _repo;
|
||||
|
||||
public IndexerDefinitionVersionService(IIndexerDefinitionVersionRepository repo)
|
||||
{
|
||||
_repo = repo;
|
||||
}
|
||||
|
||||
public IndexerDefinitionVersion Get(int indexerVersionId)
|
||||
{
|
||||
return _repo.Get(indexerVersionId);
|
||||
}
|
||||
|
||||
public IndexerDefinitionVersion GetByDefId(string defId)
|
||||
{
|
||||
return _repo.GetByDefId(defId);
|
||||
}
|
||||
|
||||
public List<IndexerDefinitionVersion> All()
|
||||
{
|
||||
return _repo.All().ToList();
|
||||
}
|
||||
|
||||
public IndexerDefinitionVersion Add(IndexerDefinitionVersion defVersion)
|
||||
{
|
||||
_repo.Insert(defVersion);
|
||||
|
||||
return defVersion;
|
||||
}
|
||||
|
||||
public IndexerDefinitionVersion Upsert(IndexerDefinitionVersion defVersion)
|
||||
{
|
||||
var existing = _repo.GetByDefId(defVersion.DefinitionId);
|
||||
|
||||
if (existing != null)
|
||||
{
|
||||
defVersion.Id = existing.Id;
|
||||
}
|
||||
|
||||
defVersion = _repo.Upsert(defVersion);
|
||||
|
||||
return defVersion;
|
||||
}
|
||||
|
||||
public void Delete(int indexerVersionId)
|
||||
{
|
||||
_repo.Delete(indexerVersionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
|
||||
var mainPage = await ExecuteAuth(new HttpRequest(Settings.BaseUrl));
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = Common.Http.HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
requestBuilder.SetCookies(mainPage.GetCookies());
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
|
||||
if (isSearch)
|
||||
{
|
||||
request.HttpRequest.Method = HttpMethod.Post;
|
||||
request.HttpRequest.Method = NzbDrone.Common.Http.HttpMethod.POST;
|
||||
var postData = new NameValueCollection
|
||||
{
|
||||
{ "do", "search" },
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Html.Parser;
|
||||
@@ -58,7 +57,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
};
|
||||
|
||||
var loginPage = await ExecuteAuth(new HttpRequest(LoginUrl));
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
requestBuilder.SetCookies(loginPage.GetCookies());
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Html.Parser;
|
||||
@@ -57,7 +56,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
AllowAutoRedirect = true
|
||||
};
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
|
||||
var cookies = Cookies;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
@@ -106,7 +105,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Avistaz
|
||||
LogResponseContent = true
|
||||
};
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
|
||||
var authLoginRequest = requestBuilder
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
@@ -56,7 +55,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
AllowAutoRedirect = true
|
||||
};
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
|
||||
var cookies = Cookies;
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Dom;
|
||||
@@ -80,7 +79,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
|
||||
var loginPage = await ExecuteAuth(new HttpRequest(LoginUrl));
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
requestBuilder.SetCookies(loginPage.GetCookies());
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using FluentValidation;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
@@ -111,7 +110,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
var request = new HttpRequest(searchUrl, HttpAccept.Json);
|
||||
|
||||
request.Headers.Add("Content-type", "application/json");
|
||||
request.Method = HttpMethod.Post;
|
||||
request.Method = HttpMethod.POST;
|
||||
request.SetContent(body.ToJson());
|
||||
|
||||
var indexerRequest = new IndexerRequest(request);
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
{
|
||||
var generator = _generatorCache.Get(Settings.DefinitionFile, () =>
|
||||
new CardigannRequestGenerator(_configService,
|
||||
_definitionService.GetCachedDefinition(Settings.DefinitionFile),
|
||||
_definitionService.GetDefinition(Settings.DefinitionFile),
|
||||
_logger)
|
||||
{
|
||||
HttpClient = _httpClient,
|
||||
@@ -57,7 +57,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
public override IParseIndexerResponse GetParser()
|
||||
{
|
||||
return new CardigannParser(_configService,
|
||||
_definitionService.GetCachedDefinition(Settings.DefinitionFile),
|
||||
_definitionService.GetDefinition(Settings.DefinitionFile),
|
||||
_logger)
|
||||
{
|
||||
Settings = Settings
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Html.Dom;
|
||||
@@ -185,7 +184,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
var requestBuilder = new HttpRequestBuilder(loginUrl)
|
||||
{
|
||||
LogResponseContent = true,
|
||||
Method = HttpMethod.Post,
|
||||
Method = HttpMethod.POST,
|
||||
AllowAutoRedirect = true,
|
||||
SuppressHttpError = true,
|
||||
Encoding = _encoding
|
||||
@@ -330,7 +329,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
var requestBuilder = new HttpRequestBuilder(captchaUrl.ToString())
|
||||
{
|
||||
LogResponseContent = true,
|
||||
Method = HttpMethod.Get,
|
||||
Method = HttpMethod.GET,
|
||||
Encoding = _encoding
|
||||
};
|
||||
|
||||
@@ -395,7 +394,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
var requestBuilder = new HttpRequestBuilder(submitUrl.ToString())
|
||||
{
|
||||
LogResponseContent = true,
|
||||
Method = HttpMethod.Post,
|
||||
Method = HttpMethod.POST,
|
||||
AllowAutoRedirect = true,
|
||||
Encoding = _encoding
|
||||
};
|
||||
@@ -424,7 +423,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
var requestBuilder = new HttpRequestBuilder(submitUrl.ToString())
|
||||
{
|
||||
LogResponseContent = true,
|
||||
Method = HttpMethod.Post,
|
||||
Method = HttpMethod.POST,
|
||||
AllowAutoRedirect = true,
|
||||
SuppressHttpError = true,
|
||||
Encoding = _encoding
|
||||
@@ -467,7 +466,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
var requestBuilder = new HttpRequestBuilder(loginUrl)
|
||||
{
|
||||
LogResponseContent = true,
|
||||
Method = HttpMethod.Get,
|
||||
Method = HttpMethod.GET,
|
||||
SuppressHttpError = true,
|
||||
Encoding = _encoding
|
||||
};
|
||||
@@ -492,7 +491,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
var requestBuilder = new HttpRequestBuilder(loginUrl)
|
||||
{
|
||||
LogResponseContent = true,
|
||||
Method = HttpMethod.Get,
|
||||
Method = HttpMethod.GET,
|
||||
SuppressHttpError = true,
|
||||
Encoding = _encoding
|
||||
};
|
||||
@@ -566,7 +565,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
var requestBuilder = new HttpRequestBuilder(loginUrl.AbsoluteUri)
|
||||
{
|
||||
LogResponseContent = true,
|
||||
Method = HttpMethod.Get,
|
||||
Method = HttpMethod.GET,
|
||||
Encoding = _encoding
|
||||
};
|
||||
|
||||
@@ -667,21 +666,21 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
Dictionary<string, string> pairs = null;
|
||||
var queryCollection = new NameValueCollection();
|
||||
|
||||
var method = HttpMethod.Get;
|
||||
var method = HttpMethod.GET;
|
||||
if (string.Equals(request.Method, "post", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
method = HttpMethod.Post;
|
||||
method = HttpMethod.POST;
|
||||
pairs = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
foreach (var input in request.Inputs)
|
||||
{
|
||||
var value = ApplyGoTemplateText(input.Value, variables);
|
||||
if (method == HttpMethod.Get)
|
||||
if (method == HttpMethod.GET)
|
||||
{
|
||||
queryCollection.Add(input.Key, value);
|
||||
}
|
||||
else if (method == HttpMethod.Post)
|
||||
else if (method == HttpMethod.POST)
|
||||
{
|
||||
pairs.Add(input.Key, value);
|
||||
}
|
||||
@@ -708,7 +707,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
httpRequest.Method = method;
|
||||
|
||||
// Add form data for POST requests
|
||||
if (method == HttpMethod.Post)
|
||||
if (method == HttpMethod.POST)
|
||||
{
|
||||
foreach (var param in pairs)
|
||||
{
|
||||
@@ -725,7 +724,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
public async Task<HttpRequest> DownloadRequest(Uri link)
|
||||
{
|
||||
Cookies = GetCookies();
|
||||
var method = HttpMethod.Get;
|
||||
var method = HttpMethod.GET;
|
||||
var headers = new Dictionary<string, string>();
|
||||
|
||||
var variables = GetBaseTemplateVariables();
|
||||
@@ -760,7 +759,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
|
||||
if (download.Method == "post")
|
||||
{
|
||||
method = HttpMethod.Post;
|
||||
method = HttpMethod.POST;
|
||||
}
|
||||
|
||||
if (download.Infohash != null)
|
||||
@@ -1015,11 +1014,11 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
// HttpUtility.UrlPathEncode seems to only encode spaces, we use UrlEncode and replace + with %20 as a workaround
|
||||
var searchUrl = ResolvePath(ApplyGoTemplateText(searchPath.Path, variables, WebUtility.UrlEncode).Replace("+", "%20")).AbsoluteUri;
|
||||
var queryCollection = new List<KeyValuePair<string, string>>();
|
||||
var method = HttpMethod.Get;
|
||||
var method = HttpMethod.GET;
|
||||
|
||||
if (string.Equals(searchPath.Method, "post", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
method = HttpMethod.Post;
|
||||
method = HttpMethod.POST;
|
||||
}
|
||||
|
||||
var inputsList = new List<Dictionary<string, string>>();
|
||||
@@ -1065,7 +1064,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
}
|
||||
}
|
||||
|
||||
if (method == HttpMethod.Get)
|
||||
if (method == HttpMethod.GET)
|
||||
{
|
||||
if (queryCollection.Count > 0)
|
||||
{
|
||||
@@ -1080,7 +1079,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
|
||||
requestbuilder.Method = method;
|
||||
|
||||
// Add FormData for searchs that POST
|
||||
if (method == HttpMethod.Post)
|
||||
if (method == HttpMethod.POST)
|
||||
{
|
||||
foreach (var param in queryCollection)
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
public class DanishBytes : TorrentIndexerBase<DanishBytesSettings>
|
||||
{
|
||||
public override string Name => "DanishBytes";
|
||||
public override string[] IndexerUrls => new string[] { "https://danishbytes.club/", "https://danishbytes2.org/" };
|
||||
public override string[] IndexerUrls => new string[] { "https://danishbytes.club/" };
|
||||
public override string Description => "DanishBytes is a Private Danish Tracker";
|
||||
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
|
||||
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Http;
|
||||
@@ -57,7 +56,7 @@ namespace NzbDrone.Core.Indexers.Gazelle
|
||||
LogResponseContent = true
|
||||
};
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
|
||||
var cookies = Cookies;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
@@ -51,7 +50,7 @@ namespace NzbDrone.Core.Indexers.HDBits
|
||||
.Resource("/api/torrents")
|
||||
.Build();
|
||||
|
||||
request.Method = HttpMethod.Post;
|
||||
request.Method = HttpMethod.POST;
|
||||
const string appJson = "application/json";
|
||||
request.Headers.Accept = appJson;
|
||||
request.Headers.ContentType = appJson;
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
@@ -58,7 +57,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
AllowAutoRedirect = true
|
||||
};
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
|
||||
var cookies = Cookies;
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Html.Parser;
|
||||
@@ -53,7 +52,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
LogResponseContent = true
|
||||
};
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
|
||||
var cookies = Cookies;
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Html.Parser;
|
||||
using FluentValidation;
|
||||
@@ -55,7 +54,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
LogResponseContent = true
|
||||
};
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
|
||||
var cookies = Cookies;
|
||||
|
||||
@@ -1,341 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using AngleSharp.Dom;
|
||||
using AngleSharp.Html.Dom;
|
||||
using AngleSharp.Html.Parser;
|
||||
using FluentValidation;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.Definitions;
|
||||
|
||||
public class MoreThanTV : TorrentIndexerBase<MoreThanTVSettings>
|
||||
{
|
||||
public override string Name => "MoreThanTV";
|
||||
public override string[] IndexerUrls => new[] { "https://www.morethantv.me/" };
|
||||
public override string Description => "Private torrent tracker for TV / MOVIES";
|
||||
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
|
||||
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
|
||||
public override IndexerCapabilities Capabilities => SetCapabilities();
|
||||
public override bool FollowRedirect => true;
|
||||
|
||||
public MoreThanTV(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger)
|
||||
: base(httpClient, eventAggregator, indexerStatusService, configService, logger)
|
||||
{
|
||||
}
|
||||
|
||||
public override IIndexerRequestGenerator GetRequestGenerator()
|
||||
=> new MoreThanTVRequestGenerator(Settings, Capabilities);
|
||||
|
||||
public override IParseIndexerResponse GetParser()
|
||||
=> new MoreThanTVParser
|
||||
{
|
||||
Settings = Settings
|
||||
};
|
||||
|
||||
private IndexerCapabilities SetCapabilities()
|
||||
{
|
||||
var caps = new IndexerCapabilities
|
||||
{
|
||||
TvSearchParams = new List<TvSearchParam>
|
||||
{
|
||||
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep
|
||||
},
|
||||
MovieSearchParams = new List<MovieSearchParam>
|
||||
{
|
||||
MovieSearchParam.Q
|
||||
}
|
||||
};
|
||||
|
||||
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.Movies, "Movies");
|
||||
caps.Categories.AddCategoryMapping(2, NewznabStandardCategory.TV, "TV");
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
protected override IDictionary<string, string> GetCookies()
|
||||
{
|
||||
return CookieUtil.CookieHeaderToDictionary(Settings.Cookie);
|
||||
}
|
||||
}
|
||||
|
||||
public class MoreThanTVRequestGenerator : IIndexerRequestGenerator
|
||||
{
|
||||
private MoreThanTVSettings Settings { get; }
|
||||
private IndexerCapabilities Capabilities { get; }
|
||||
|
||||
private NameValueCollection BrowserHeaders { get; }
|
||||
|
||||
public MoreThanTVRequestGenerator(MoreThanTVSettings settings, IndexerCapabilities capabilities)
|
||||
{
|
||||
Settings = settings;
|
||||
Capabilities = capabilities;
|
||||
BrowserHeaders = new NameValueCollection()
|
||||
{
|
||||
{ "referer", settings.BaseUrl },
|
||||
{ "Upgrade-Insecure-Requests", "1" },
|
||||
{ "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36" }
|
||||
};
|
||||
}
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
|
||||
=> PerformRequest(searchCriteria);
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(MusicSearchCriteria searchCriteria)
|
||||
=> PerformRequest(searchCriteria);
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(TvSearchCriteria searchCriteria)
|
||||
=> PerformRequest(searchCriteria);
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(BookSearchCriteria searchCriteria)
|
||||
=> PerformRequest(searchCriteria);
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(BasicSearchCriteria searchCriteria)
|
||||
=> PerformRequest(searchCriteria);
|
||||
|
||||
public Func<IDictionary<string, string>> GetCookies { get; set; }
|
||||
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
|
||||
|
||||
private IndexerPageableRequestChain PerformRequest(SearchCriteriaBase query)
|
||||
{
|
||||
var chain = new IndexerPageableRequestChain();
|
||||
|
||||
var requests = new List<IndexerRequest> { new (new HttpRequest(GetTorrentSearchUrl(query)) { Headers = new HttpHeader(BrowserHeaders), AllowAutoRedirect = true }) };
|
||||
|
||||
if (query is TvSearchCriteria tvSearchCriteria)
|
||||
{
|
||||
// Always search for torrent groups (complete seasons) too
|
||||
var seasonRegex = new Regex(@".*\s[Ss]{1}\d{2}([Ee]{1}\d{2,3})?$", RegexOptions.Compiled);
|
||||
var seasonMatch = seasonRegex.Match(query.SanitizedSearchTerm);
|
||||
if (seasonMatch.Success)
|
||||
{
|
||||
var seasonReplaceRegex = new Regex(@"[Ss]{1}\d{2}([Ee]{1}\d{2,3})?", RegexOptions.Compiled);
|
||||
var newSearchQuery = seasonReplaceRegex.Replace(query.SanitizedSearchTerm, $"Season {tvSearchCriteria.Season}");
|
||||
requests.Add(new IndexerRequest(new HttpRequest(GetTorrentSearchUrl(query, newSearchQuery)) { Headers = new HttpHeader(BrowserHeaders), AllowAutoRedirect = true }));
|
||||
}
|
||||
}
|
||||
|
||||
chain.Add(requests);
|
||||
|
||||
return chain;
|
||||
}
|
||||
|
||||
private string GetTorrentSearchUrl(SearchCriteriaBase query, string overrideSearchTerm = null)
|
||||
{
|
||||
var qc = new NameValueCollection
|
||||
{
|
||||
{ "action", "advanced" },
|
||||
{ "sizetype", "gb" },
|
||||
{ "sizerange", "0.01" },
|
||||
{ "title", overrideSearchTerm ?? GetSearchString(query.SanitizedSearchTerm) }
|
||||
};
|
||||
|
||||
switch (query)
|
||||
{
|
||||
case MovieSearchCriteria:
|
||||
qc.Add("filter_cat[1]", "1"); // HD Movies
|
||||
qc.Add("filter_cat[2]", "1"); // SD Movies
|
||||
break;
|
||||
case TvSearchCriteria:
|
||||
qc.Add("filter_cat[3]", "1"); // HD EPISODE
|
||||
qc.Add("filter_cat[4]", "1"); // SD Episode
|
||||
qc.Add("filter_cat[5]", "1"); // HD Season
|
||||
qc.Add("filter_cat[6]", "1"); // SD Season
|
||||
break;
|
||||
}
|
||||
|
||||
return $"{Settings.BaseUrl}torrents.php?{qc.GetQueryString()}";
|
||||
}
|
||||
|
||||
private string GetSearchString(string input)
|
||||
{
|
||||
input = input.Replace("Marvels", "Marvel"); // strip 's for better results
|
||||
var regex = new Regex(@"(S\d{2})$", RegexOptions.Compiled);
|
||||
return regex.Replace(input, "$1*"); // If we're just seaching for a season (no episode) append an * to include all episodes of that season.
|
||||
}
|
||||
}
|
||||
|
||||
public class MoreThanTVParser : IParseIndexerResponse
|
||||
{
|
||||
public MoreThanTVSettings Settings { get; init; }
|
||||
|
||||
public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
|
||||
{
|
||||
var releases = new List<ReleaseInfo>();
|
||||
|
||||
try
|
||||
{
|
||||
var parser = new HtmlParser();
|
||||
var document = parser.ParseDocument(indexerResponse.Content);
|
||||
var torrents = document.QuerySelectorAll("#torrent_table > tbody > tr.torrent");
|
||||
var movies = new[] { "movie" };
|
||||
var tv = new[] { "season", "episode" };
|
||||
|
||||
// Loop through all torrents checking for groups
|
||||
foreach (var torrent in torrents)
|
||||
{
|
||||
// Parse required data
|
||||
var torrentGroup = torrent.QuerySelectorAll("table a[href^=\"/torrents.php?action=download\"]");
|
||||
foreach (var downloadAnchor in torrentGroup)
|
||||
{
|
||||
var title = downloadAnchor.ParentElement.ParentElement.ParentElement.TextContent.Trim();
|
||||
title = CleanUpTitle(title);
|
||||
|
||||
var category = torrent.QuerySelector(".cats_col div").GetAttribute("title");
|
||||
|
||||
// default to Other
|
||||
var indexerCategory = NewznabStandardCategory.Other;
|
||||
|
||||
if (movies.Any(category.Contains))
|
||||
{
|
||||
indexerCategory = NewznabStandardCategory.Movies;
|
||||
}
|
||||
else if (tv.Any(category.Contains))
|
||||
{
|
||||
indexerCategory = NewznabStandardCategory.TV;
|
||||
}
|
||||
|
||||
releases.Add(GetReleaseInfo(torrent, downloadAnchor, title, indexerCategory));
|
||||
}
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Error while parsing torrent response", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gather Release info from torrent table. Target using css
|
||||
/// </summary>
|
||||
/// <param name="row"></param>
|
||||
/// <param name="downloadAnchor"></param>
|
||||
/// <param name="title"></param>
|
||||
/// <param name="category"></param>
|
||||
/// <returns></returns>
|
||||
private ReleaseInfo GetReleaseInfo(IElement row, IElement downloadAnchor, string title, IndexerCategory category)
|
||||
{
|
||||
// count from bottom
|
||||
const int FILES_COL = 8;
|
||||
/*const int COMMENTS_COL = 7;*/
|
||||
const int DATE_COL = 6;
|
||||
const int FILESIZE_COL = 5;
|
||||
const int SNATCHED_COL = 4;
|
||||
const int SEEDS_COL = 3;
|
||||
const int LEECHERS_COL = 2;
|
||||
/*const int USER_COL = 1;*/
|
||||
|
||||
var downloadAnchorHref = (downloadAnchor as IHtmlAnchorElement).Href;
|
||||
var queryParams = HttpUtility.ParseQueryString(downloadAnchorHref, Encoding.UTF8);
|
||||
var torrentId = queryParams["id"];
|
||||
|
||||
var qFiles = row.QuerySelector("td:nth-last-child(" + FILES_COL + ")").TextContent;
|
||||
|
||||
var fileCount = ParseUtil.CoerceInt(qFiles);
|
||||
var qPublishDate = row.QuerySelector("td:nth-last-child(" + DATE_COL + ") .time").Attributes["title"].Value;
|
||||
var publishDate = DateTime.ParseExact(qPublishDate, "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();
|
||||
var qPoster = row.QuerySelector("div.tp-banner img")?.GetAttribute("src");
|
||||
var poster = (qPoster != null && !qPoster.Contains("caticons")) ? qPoster : null;
|
||||
var description = row.QuerySelector("div.tags")?.TextContent.Trim();
|
||||
var fileSize = row.QuerySelector("td:nth-last-child(" + FILESIZE_COL + ")").TextContent.Trim();
|
||||
var snatched = row.QuerySelector("td:nth-last-child(" + SNATCHED_COL + ")").TextContent.Trim();
|
||||
var seeds = row.QuerySelector("td:nth-last-child(" + SEEDS_COL + ")").TextContent.Trim();
|
||||
var leechs = row.QuerySelector("td:nth-last-child(" + LEECHERS_COL + ")").TextContent.Trim();
|
||||
|
||||
if (fileSize.Length <= 0 || snatched.Length <= 0 || seeds.Length <= 0 || leechs.Length <= 0)
|
||||
{
|
||||
// Size (xx.xx GB[ (Max)]) Snatches (xx) Seeders (xx) Leechers (xx)
|
||||
throw new Exception($"We expected 4 torrent datas.");
|
||||
}
|
||||
|
||||
var detailUrl = $"{Settings.BaseUrl}details.php";
|
||||
|
||||
var size = ParseUtil.GetBytes(fileSize);
|
||||
var grabs = int.Parse(snatched, NumberStyles.AllowThousands, CultureInfo.InvariantCulture);
|
||||
var seeders = int.Parse(seeds, NumberStyles.AllowThousands, CultureInfo.InvariantCulture);
|
||||
var leechers = int.Parse(leechs, NumberStyles.AllowThousands, CultureInfo.InvariantCulture);
|
||||
var detailsUrl = $"{detailUrl}?torrentid={torrentId}";
|
||||
var downloadUrl = $"{detailUrl}?action=download&id={torrentId}";
|
||||
var categories = new List<IndexerCategory> { category };
|
||||
|
||||
return new TorrentInfo
|
||||
{
|
||||
Title = title,
|
||||
Categories = categories,
|
||||
DownloadUrl = downloadUrl,
|
||||
PublishDate = publishDate,
|
||||
PosterUrl = poster,
|
||||
Description = description,
|
||||
Seeders = seeders,
|
||||
Peers = seeders + leechers,
|
||||
Files = fileCount,
|
||||
Size = size,
|
||||
Grabs = grabs,
|
||||
Guid = downloadUrl,
|
||||
InfoUrl = detailsUrl,
|
||||
DownloadVolumeFactor = 0, // ratioless tracker
|
||||
UploadVolumeFactor = 1
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean Up any title stuff
|
||||
/// </summary>
|
||||
/// <param name="title"></param>
|
||||
/// <returns></returns>
|
||||
private string CleanUpTitle(string title)
|
||||
{
|
||||
return title
|
||||
.Replace(".", " ")
|
||||
.Replace("4K", "2160p"); // sonarr cleanup
|
||||
}
|
||||
|
||||
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
|
||||
}
|
||||
|
||||
public class MoreThanTVSettingsValidator : AbstractValidator<MoreThanTVSettings>
|
||||
{
|
||||
public MoreThanTVSettingsValidator()
|
||||
{
|
||||
RuleFor(c => c.Cookie).NotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public class MoreThanTVSettings : IIndexerSettings
|
||||
{
|
||||
private static readonly MoreThanTVSettingsValidator Validator = new ();
|
||||
|
||||
public MoreThanTVSettings()
|
||||
{
|
||||
Cookie = "";
|
||||
}
|
||||
|
||||
[FieldDefinition(1, Label = "Base Url", Type = FieldType.Select, SelectOptionsProviderAction = "getUrls", HelpText = "Select which baseurl Prowlarr will use for requests to the site")]
|
||||
public string BaseUrl { get; set; }
|
||||
|
||||
[FieldDefinition(2, Label = "Cookie", HelpText = "Enter the cookies for the site, just copy everything after 'cookie:' from the request headers to the site", HelpLink = "https://wiki.servarr.com/prowlarr/faq#finding-cookies")]
|
||||
public string Cookie { get; set; }
|
||||
|
||||
[FieldDefinition(3)]
|
||||
public IndexerBaseSettings BaseSettings { get; set; } = new IndexerBaseSettings();
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
@@ -54,7 +53,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
LogResponseContent = true
|
||||
};
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
|
||||
var cookies = Cookies;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using NLog;
|
||||
@@ -51,7 +50,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||
|
||||
var request = new HttpRequest(url, HttpAccept.Rss);
|
||||
request.AllowAutoRedirect = true;
|
||||
request.Method = HttpMethod.Get;
|
||||
request.Method = HttpMethod.GET;
|
||||
|
||||
HttpResponse response;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
@@ -80,7 +79,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
{
|
||||
LogResponseContent = true,
|
||||
AllowAutoRedirect = true,
|
||||
Method = HttpMethod.Post
|
||||
Method = HttpMethod.POST
|
||||
};
|
||||
|
||||
var authLoginCheckRequest = requestBuilder3
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
@@ -29,7 +28,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
public override string Language => "ru-ru";
|
||||
public override Encoding Encoding => Encoding.GetEncoding("windows-1251");
|
||||
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
|
||||
public override IndexerPrivacy Privacy => IndexerPrivacy.SemiPrivate;
|
||||
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
|
||||
public override IndexerCapabilities Capabilities => SetCapabilities();
|
||||
|
||||
public PornoLab(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger)
|
||||
@@ -53,7 +52,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
{
|
||||
LogResponseContent = true,
|
||||
AllowAutoRedirect = true,
|
||||
Method = HttpMethod.Post
|
||||
Method = HttpMethod.POST
|
||||
};
|
||||
|
||||
var authLoginRequest = requestBuilder
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
@@ -60,7 +59,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
|
||||
var loginPage = await ExecuteAuth(new HttpRequest(Settings.BaseUrl + "login.php"));
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
requestBuilder.SetCookies(loginPage.GetCookies());
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Html.Parser;
|
||||
using FluentValidation;
|
||||
@@ -59,7 +58,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
|
||||
var loginPage = await ExecuteAuth(new HttpRequest(Settings.BaseUrl + "login.php"));
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
requestBuilder.SetCookies(loginPage.GetCookies());
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
@@ -32,7 +31,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
public override string Language => "ru-org";
|
||||
public override Encoding Encoding => Encoding.GetEncoding("windows-1251");
|
||||
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
|
||||
public override IndexerPrivacy Privacy => IndexerPrivacy.SemiPrivate;
|
||||
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
|
||||
public override IndexerCapabilities Capabilities => SetCapabilities();
|
||||
|
||||
public RuTracker(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger)
|
||||
@@ -58,7 +57,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
AllowAutoRedirect = true
|
||||
};
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
|
||||
var cookies = Cookies;
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Mime;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -76,7 +75,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
{
|
||||
LogResponseContent = true,
|
||||
AllowAutoRedirect = true,
|
||||
Method = HttpMethod.Post,
|
||||
Method = HttpMethod.POST,
|
||||
};
|
||||
|
||||
var request = requestBuilder.Build();
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
@@ -58,7 +57,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
{
|
||||
var requestBuilder = new HttpRequestBuilder(string.Format("{0}/{1}", Settings.BaseUrl.TrimEnd('/'), "checkpoint/API"))
|
||||
{
|
||||
Method = HttpMethod.Post,
|
||||
Method = HttpMethod.POST,
|
||||
LogResponseContent = true,
|
||||
AllowAutoRedirect = true
|
||||
};
|
||||
@@ -78,7 +77,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
|
||||
var requestBuilder2 = new HttpRequestBuilder(string.Format("{0}/{1}", Settings.BaseUrl.TrimEnd('/'), "checkpoint/"))
|
||||
{
|
||||
Method = HttpMethod.Post,
|
||||
Method = HttpMethod.POST,
|
||||
LogResponseContent = true,
|
||||
AllowAutoRedirect = true
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
@@ -60,7 +59,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
AllowAutoRedirect = true
|
||||
};
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
|
||||
var cookies = Cookies;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation;
|
||||
@@ -55,7 +54,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
LogResponseContent = true
|
||||
};
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
|
||||
var cookies = Cookies;
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Html.Parser;
|
||||
@@ -64,7 +63,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
var json1 = JObject.Parse(loginPage.Content);
|
||||
var captchaSelection = json1["images"][0]["hash"];
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
requestBuilder.SetCookies(loginPage.GetCookies());
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -80,7 +79,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
LogResponseContent = true
|
||||
};
|
||||
|
||||
requestBuilder.Method = HttpMethod.Post;
|
||||
requestBuilder.Method = HttpMethod.POST;
|
||||
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
requestBuilder.SetCookies(loginPage.GetCookies());
|
||||
|
||||
@@ -103,7 +102,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
||||
LogResponseContent = true
|
||||
};
|
||||
|
||||
requestBuilder2.Method = HttpMethod.Post;
|
||||
requestBuilder2.Method = HttpMethod.POST;
|
||||
requestBuilder2.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
||||
requestBuilder2.SetCookies(response.GetCookies());
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Indexers.Cardigann;
|
||||
using NzbDrone.Core.Indexers.Newznab;
|
||||
using NzbDrone.Core.IndexerVersions;
|
||||
@@ -46,27 +45,16 @@ namespace NzbDrone.Core.Indexers
|
||||
public override List<IndexerDefinition> All()
|
||||
{
|
||||
var definitions = base.All();
|
||||
var filteredDefinitions = new List<IndexerDefinition>();
|
||||
|
||||
foreach (var definition in definitions)
|
||||
{
|
||||
if (definition.Implementation == typeof(Cardigann.Cardigann).Name)
|
||||
{
|
||||
try
|
||||
{
|
||||
MapCardigannDefinition(definition);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Skip indexer if we fail in Cardigann mapping
|
||||
_logger.Debug("Indexer {0} has no definition", definition.Name);
|
||||
}
|
||||
MapCardigannDefinition(definition);
|
||||
}
|
||||
|
||||
filteredDefinitions.Add(definition);
|
||||
}
|
||||
|
||||
return filteredDefinitions;
|
||||
return definitions;
|
||||
}
|
||||
|
||||
public override IndexerDefinition Get(int id)
|
||||
@@ -75,14 +63,7 @@ namespace NzbDrone.Core.Indexers
|
||||
|
||||
if (definition.Implementation == typeof(Cardigann.Cardigann).Name)
|
||||
{
|
||||
try
|
||||
{
|
||||
MapCardigannDefinition(definition);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new ModelNotFoundException(typeof(IndexerDefinition), id);
|
||||
}
|
||||
MapCardigannDefinition(definition);
|
||||
}
|
||||
|
||||
return definition;
|
||||
@@ -96,7 +77,7 @@ namespace NzbDrone.Core.Indexers
|
||||
private void MapCardigannDefinition(IndexerDefinition definition)
|
||||
{
|
||||
var settings = (CardigannSettings)definition.Settings;
|
||||
var defFile = _definitionService.GetCachedDefinition(settings.DefinitionFile);
|
||||
var defFile = _definitionService.GetDefinition(settings.DefinitionFile);
|
||||
definition.ExtraFields = defFile.Settings;
|
||||
|
||||
if (defFile.Login?.Captcha != null && !definition.ExtraFields.Any(x => x.Type == "cardigannCaptcha"))
|
||||
|
||||
@@ -28,17 +28,17 @@ namespace NzbDrone.Core.Indexers
|
||||
{
|
||||
if (indexer.Id > 0 && ((IIndexerSettings)indexer.Settings).BaseSettings.GrabLimit.HasValue)
|
||||
{
|
||||
var grabCount = _historyService.CountSince(indexer.Id, DateTime.Now.AddHours(-24), new List<HistoryEventType> { HistoryEventType.ReleaseGrabbed });
|
||||
var grabLimit = ((IIndexerSettings)indexer.Settings).BaseSettings.GrabLimit;
|
||||
var grabCount = _historyService.CountSince(indexer.Id, DateTime.Now.StartOfDay(), new List<HistoryEventType> { HistoryEventType.ReleaseGrabbed });
|
||||
var grabLimit = ((IIndexerSettings)indexer.Settings).BaseSettings.QueryLimit;
|
||||
|
||||
if (grabCount > grabLimit)
|
||||
{
|
||||
_logger.Info("Indexer {0} has exceeded maximum grab limit for last 24 hours", indexer.Name);
|
||||
_logger.Info("Indexer {0} has exceeded maximum grab limit for today", indexer.Name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_logger.Debug("Indexer {0} has performed {1} of possible {2} grabs in last 24 hours, proceeding", indexer.Name, grabCount, grabLimit);
|
||||
_logger.Debug("Indexer {0} has performed {1} of possible {2} grabs for today, proceeding", indexer.Name, grabCount, grabLimit);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -48,17 +48,17 @@ namespace NzbDrone.Core.Indexers
|
||||
{
|
||||
if (indexer.Id > 0 && ((IIndexerSettings)indexer.Settings).BaseSettings.QueryLimit.HasValue)
|
||||
{
|
||||
var queryCount = _historyService.CountSince(indexer.Id, DateTime.Now.AddHours(-24), new List<HistoryEventType> { HistoryEventType.IndexerQuery, HistoryEventType.IndexerRss });
|
||||
var queryCount = _historyService.CountSince(indexer.Id, DateTime.Now.StartOfDay(), new List<HistoryEventType> { HistoryEventType.IndexerQuery, HistoryEventType.IndexerRss });
|
||||
var queryLimit = ((IIndexerSettings)indexer.Settings).BaseSettings.QueryLimit;
|
||||
|
||||
if (queryCount > queryLimit)
|
||||
{
|
||||
_logger.Info("Indexer {0} has exceeded maximum query limit for last 24 hours", indexer.Name);
|
||||
_logger.Info("Indexer {0} has exceeded maximum query limit for today", indexer.Name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_logger.Debug("Indexer {0} has performed {1} of possible {2} queries in last 24 hours, proceeding", indexer.Name, queryCount, queryLimit);
|
||||
_logger.Debug("Indexer {0} has performed {1} of possible {2} queries for today, proceeding", indexer.Name, queryCount, queryLimit);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -128,8 +128,10 @@ namespace NzbDrone.Core.Instrumentation
|
||||
private void WriteSqliteLog(Log log, string connectionString)
|
||||
{
|
||||
using (var connection =
|
||||
new SQLiteConnection(connectionString).OpenAndReturn())
|
||||
SQLiteFactory.Instance.CreateConnection())
|
||||
{
|
||||
connection.ConnectionString = connectionString;
|
||||
connection.Open();
|
||||
using (var sqlCommand = connection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = INSERT_COMMAND;
|
||||
|
||||
@@ -85,7 +85,6 @@
|
||||
"CouldNotConnectSignalR": "Could not connect to SignalR, UI won't update",
|
||||
"Custom": "Custom",
|
||||
"CustomFilters": "Custom Filters",
|
||||
"Database": "Database",
|
||||
"Date": "Date",
|
||||
"Dates": "Dates",
|
||||
"DBMigration": "DB Migration",
|
||||
@@ -170,7 +169,6 @@
|
||||
"IllRestartLater": "I'll restart later",
|
||||
"IncludeHealthWarningsHelpText": "Include Health Warnings",
|
||||
"Indexer": "Indexer",
|
||||
"IndexerAlreadySetup": "At least one instace of indexer is already setup",
|
||||
"IndexerAuth": "Indexer Auth",
|
||||
"IndexerFlags": "Indexer Flags",
|
||||
"IndexerHealthCheckNoIndexers": "No indexers enabled, Prowlarr will not return search results",
|
||||
@@ -178,7 +176,6 @@
|
||||
"IndexerLongTermStatusCheckAllClientMessage": "All indexers are unavailable due to failures for more than 6 hours",
|
||||
"IndexerLongTermStatusCheckSingleClientMessage": "Indexers unavailable due to failures for more than 6 hours: {0}",
|
||||
"IndexerObsoleteCheckMessage": "Indexers are obsolete or have been updated: {0}. Please remove and (or) re-add to Prowlarr",
|
||||
"IndexerNoDefCheckMessage": "Indexers have no definition and will not work: {0}. Please remove and (or) re-add to Prowlarr",
|
||||
"IndexerPriority": "Indexer Priority",
|
||||
"IndexerPriorityHelpText": "Indexer Priority from 1 (Highest) to 50 (Lowest). Default: 25.",
|
||||
"IndexerProxies": "Indexer Proxies",
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Net.Http;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
@@ -30,7 +29,7 @@ namespace NzbDrone.Core.Notifications.Discord
|
||||
.Accept(HttpAccept.Json)
|
||||
.Build();
|
||||
|
||||
request.Method = HttpMethod.Post;
|
||||
request.Method = HttpMethod.POST;
|
||||
request.Headers.ContentType = "application/json";
|
||||
request.SetContent(payload.ToJson());
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
@@ -28,7 +27,7 @@ namespace NzbDrone.Core.Notifications.Join
|
||||
|
||||
public void SendNotification(string title, string message, JoinSettings settings)
|
||||
{
|
||||
var method = HttpMethod.Get;
|
||||
var method = HttpMethod.GET;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
@@ -101,7 +100,7 @@ namespace NzbDrone.Core.Notifications.PushBullet
|
||||
|
||||
var request = requestBuilder.Build();
|
||||
|
||||
request.Method = HttpMethod.Get;
|
||||
request.Method = HttpMethod.GET;
|
||||
request.AddBasicAuthentication(settings.ApiKey, string.Empty);
|
||||
|
||||
var response = _httpClient.Execute(request);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
|
||||
@@ -23,7 +22,7 @@ namespace NzbDrone.Core.Notifications.SendGrid
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = BuildRequest(settings, "mail/send", HttpMethod.Post);
|
||||
var request = BuildRequest(settings, "mail/send", HttpMethod.POST);
|
||||
|
||||
var payload = new SendGridPayload
|
||||
{
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Net.Http;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
@@ -30,7 +29,7 @@ namespace NzbDrone.Core.Notifications.Slack
|
||||
.Accept(HttpAccept.Json)
|
||||
.Build();
|
||||
|
||||
request.Method = HttpMethod.Post;
|
||||
request.Method = HttpMethod.POST;
|
||||
request.Headers.ContentType = "application/json";
|
||||
request.SetContent(payload.ToJson());
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using System.Net.Http;
|
||||
using NzbDrone.Common.Http;
|
||||
|
||||
namespace NzbDrone.Core.Notifications.Webhook
|
||||
{
|
||||
public enum WebhookMethod
|
||||
{
|
||||
POST = 1,
|
||||
PUT = 2
|
||||
POST = HttpMethod.POST,
|
||||
PUT = HttpMethod.PUT
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Common.Serializer;
|
||||
@@ -28,13 +26,7 @@ namespace NzbDrone.Core.Notifications.Webhook
|
||||
.Accept(HttpAccept.Json)
|
||||
.Build();
|
||||
|
||||
request.Method = settings.Method switch
|
||||
{
|
||||
(int)WebhookMethod.POST => HttpMethod.Post,
|
||||
(int)WebhookMethod.PUT => HttpMethod.Put,
|
||||
_ => throw new ArgumentOutOfRangeException($"Invalid Webhook method {settings.Method}")
|
||||
};
|
||||
|
||||
request.Method = (HttpMethod)settings.Method;
|
||||
request.Headers.ContentType = "application/json";
|
||||
request.SetContent(body.ToJson());
|
||||
|
||||
|
||||
@@ -16,26 +16,14 @@ namespace NzbDrone.Core.Parser
|
||||
public static string NormalizeMultiSpaces(string s) =>
|
||||
new Regex(@"\s+").Replace(s.Trim(), " ");
|
||||
|
||||
private static string NormalizeNumber(string s, bool isInt = false)
|
||||
private static string NormalizeNumber(string s)
|
||||
{
|
||||
var valStr = new string(s.Where(c => char.IsDigit(c) || c == '.' || c == ',').ToArray());
|
||||
|
||||
valStr = valStr.Trim().Replace("-", "0");
|
||||
|
||||
if (isInt)
|
||||
{
|
||||
if (valStr.Contains(',') && valStr.Contains('.'))
|
||||
{
|
||||
return valStr;
|
||||
}
|
||||
|
||||
valStr = (valStr.Length == 0) ? "0" : valStr.Replace(".", ",");
|
||||
|
||||
return valStr;
|
||||
}
|
||||
|
||||
valStr = (valStr.Length == 0) ? "0" : valStr.Replace(",", ".");
|
||||
|
||||
valStr = valStr.Trim().Replace("-", "0");
|
||||
|
||||
if (valStr.Count(c => c == '.') > 1)
|
||||
{
|
||||
var lastOcc = valStr.LastIndexOf('.');
|
||||
@@ -51,17 +39,17 @@ namespace NzbDrone.Core.Parser
|
||||
|
||||
public static float CoerceFloat(string str) => float.Parse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
|
||||
public static int CoerceInt(string str) => int.Parse(NormalizeNumber(str, true), NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
public static int CoerceInt(string str) => int.Parse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
|
||||
public static long CoerceLong(string str) => long.Parse(NormalizeNumber(str, true), NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
public static long CoerceLong(string str) => long.Parse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture);
|
||||
|
||||
public static bool TryCoerceDouble(string str, out double result) => double.TryParse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
|
||||
|
||||
public static bool TryCoerceFloat(string str, out float result) => float.TryParse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
|
||||
|
||||
public static bool TryCoerceInt(string str, out int result) => int.TryParse(NormalizeNumber(str, true), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
|
||||
public static bool TryCoerceInt(string str, out int result) => int.TryParse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
|
||||
|
||||
public static bool TryCoerceLong(string str, out long result) => long.TryParse(NormalizeNumber(str, true), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
|
||||
public static bool TryCoerceLong(string str, out long result) => long.TryParse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
|
||||
|
||||
public static long? GetLongFromString(string str)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Data.SQLite;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
@@ -7,7 +6,6 @@ using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Processes;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
||||
namespace NzbDrone.Host
|
||||
@@ -101,7 +99,6 @@ namespace NzbDrone.Host
|
||||
return args;
|
||||
}
|
||||
|
||||
[EventHandleOrder(EventHandleOrder.Last)]
|
||||
public void Handle(ApplicationShutdownRequested message)
|
||||
{
|
||||
if (!_runtimeInfo.IsWindowsService)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SQLite;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
@@ -100,11 +99,6 @@ namespace NzbDrone.Host
|
||||
Logger.Info(e.Message);
|
||||
LogManager.Configuration = null;
|
||||
}
|
||||
|
||||
// Make sure there are no lingering database connections
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
SQLiteConnection.ClearAllPools();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateConsoleHostBuilder(string[] args, StartupContext context)
|
||||
|
||||
@@ -15,7 +15,6 @@ namespace Prowlarr.Api.V1.Indexers
|
||||
public class IndexerResource : ProviderResource<IndexerResource>
|
||||
{
|
||||
public string[] IndexerUrls { get; set; }
|
||||
public string DefinitionName { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Language { get; set; }
|
||||
public string Encoding { get; set; }
|
||||
@@ -52,8 +51,6 @@ namespace Prowlarr.Api.V1.Indexers
|
||||
|
||||
var resource = base.ToResource(definition);
|
||||
|
||||
resource.DefinitionName = definition.ImplementationName;
|
||||
|
||||
var infoLinkName = definition.ImplementationName;
|
||||
|
||||
if (definition.Implementation == typeof(Cardigann).Name)
|
||||
@@ -74,7 +71,6 @@ namespace Prowlarr.Api.V1.Indexers
|
||||
}
|
||||
}
|
||||
|
||||
resource.DefinitionName = settings.DefinitionFile;
|
||||
infoLinkName = settings.DefinitionFile;
|
||||
}
|
||||
|
||||
@@ -114,7 +110,7 @@ namespace Prowlarr.Api.V1.Indexers
|
||||
|
||||
var settings = (CardigannSettings)definition.Settings;
|
||||
|
||||
var cardigannDefinition = _definitionService.GetCachedDefinition(settings.DefinitionFile);
|
||||
var cardigannDefinition = _definitionService.GetDefinition(settings.DefinitionFile);
|
||||
|
||||
foreach (var field in resource.Fields)
|
||||
{
|
||||
|
||||
@@ -148,11 +148,11 @@ namespace NzbDrone.Api.V1.Indexers
|
||||
|
||||
foreach (var result in results.Releases)
|
||||
{
|
||||
result.DownloadUrl = result.DownloadUrl.IsNotNullOrWhiteSpace() ? _downloadMappingService.ConvertToProxyLink(new Uri(result.DownloadUrl), request.server, indexerDef.Id, result.Title).AbsoluteUri : null;
|
||||
result.DownloadUrl = result.DownloadUrl.IsNotNullOrWhiteSpace() ? _downloadMappingService.ConvertToProxyLink(new Uri(result.DownloadUrl), request.server, indexerDef.Id, result.Title).ToString() : null;
|
||||
|
||||
if (result.DownloadProtocol == DownloadProtocol.Torrent)
|
||||
{
|
||||
((TorrentInfo)result).MagnetUrl = ((TorrentInfo)result).MagnetUrl.IsNotNullOrWhiteSpace() ? _downloadMappingService.ConvertToProxyLink(new Uri(((TorrentInfo)result).MagnetUrl), request.server, indexerDef.Id, result.Title).AbsoluteUri : null;
|
||||
((TorrentInfo)result).MagnetUrl = ((TorrentInfo)result).MagnetUrl.IsNotNullOrWhiteSpace() ? _downloadMappingService.ConvertToProxyLink(new Uri(((TorrentInfo)result).MagnetUrl), request.server, indexerDef.Id, result.Title).ToString() : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user