Fixed issue with nzbs.org search where title contained brackets

pull/2/head
kay.one 14 years ago
parent 861026f743
commit f2b091dcd2

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.ServiceModel.Syndication; using System.ServiceModel.Syndication;
@ -159,8 +160,9 @@ namespace NzbDrone.Core.Test
ExceptionVerification.IgnoreWarns(); ExceptionVerification.IgnoreWarns();
} }
[Test] [TestCase("simpsons", 21, 23)]
public void nzbsorg_search_returns_valid_results() [TestCase("Hawaii Five-0 (2010)", 1, 5)]
public void nzbsorg_search_returns_valid_results(string title, int season, int episode)
{ {
var mocker = new AutoMoqer(); var mocker = new AutoMoqer();
@ -174,16 +176,16 @@ namespace NzbDrone.Core.Test
mocker.Resolve<HttpProvider>(); mocker.Resolve<HttpProvider>();
var result = mocker.Resolve<NzbsOrg>().FetchEpisode("Simpsons", 21, 23); var result = mocker.Resolve<NzbsOrg>().FetchEpisode(title, season, episode);
result.Should().NotBeEmpty(); result.Should().NotBeEmpty();
result.Should().OnlyContain(r => r.CleanTitle == "simpsons"); result.Should().OnlyContain(r => r.CleanTitle == Parser.NormalizeTitle(title));
result.Should().OnlyContain(r => r.SeasonNumber == 21); result.Should().OnlyContain(r => r.SeasonNumber == season);
result.Should().OnlyContain(r => r.EpisodeNumbers.Contains(23)); result.Should().OnlyContain(r => r.EpisodeNumbers.Contains(episode));
} }
[TestCase("simpsons", 21, 23)] [TestCase("simpsons", 21, 23)]
[TestCase("Hawaii Five-0 2010", 1, 5)] [TestCase("Hawaii Five-0 (2010)", 1, 5)]
public void newzbin_search_returns_valid_results(string title, int season, int episode) public void newzbin_search_returns_valid_results(string title, int season, int episode)
{ {
var mocker = new AutoMoqer(); var mocker = new AutoMoqer();
@ -275,5 +277,20 @@ namespace NzbDrone.Core.Test
result.Should().OnlyContain(r => r.SeasonNumber == 1); result.Should().OnlyContain(r => r.SeasonNumber == 1);
result.Should().OnlyContain(r => r.EpisodeNumbers.Contains(19)); result.Should().OnlyContain(r => r.EpisodeNumbers.Contains(19));
} }
[TestCase("hawaii five-0 (2010)", "hawaii+five+0+2010")]
[TestCase("this& that", "this+that")]
[TestCase("this& that", "this+that")]
public void get_query_title(string raw, string clean)
{
var result = IndexerBase.GetQueryTitle(raw);
result.Should().Be(clean);
}
} }
} }

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;
using System.ServiceModel.Syndication; using System.ServiceModel.Syndication;
using System.Text.RegularExpressions;
using System.Web; using System.Web;
using Ninject; using Ninject;
using NLog; using NLog;
@ -16,6 +17,8 @@ namespace NzbDrone.Core.Providers.Indexer
private readonly HttpProvider _httpProvider; private readonly HttpProvider _httpProvider;
protected readonly ConfigProvider _configProvider; protected readonly ConfigProvider _configProvider;
private static readonly Regex TitleSearchRegex = new Regex(@"[\W]", RegexOptions.IgnoreCase | RegexOptions.Compiled);
[Inject] [Inject]
protected IndexerBase(HttpProvider httpProvider, ConfigProvider configProvider) protected IndexerBase(HttpProvider httpProvider, ConfigProvider configProvider)
{ {
@ -58,6 +61,7 @@ namespace NzbDrone.Core.Providers.Indexer
/// <param name="episodeNumber">The episode number.</param> /// <param name="episodeNumber">The episode number.</param>
/// <returns></returns> /// <returns></returns>
protected abstract IList<String> GetSearchUrls(string seriesTitle, int seasonNumber, int episodeNumber); protected abstract IList<String> GetSearchUrls(string seriesTitle, int seasonNumber, int episodeNumber);
public abstract IList<String> GetSearchUrls(string seriesTitle, int seasonNumber, int episodeNumber);
/// <summary> /// <summary>
/// This method can be overwritten to provide indexer specific info parsing /// This method can be overwritten to provide indexer specific info parsing
@ -102,7 +106,7 @@ namespace NzbDrone.Core.Providers.Indexer
var result = new List<EpisodeParseResult>(); var result = new List<EpisodeParseResult>();
var searchUrls = GetSearchUrls(HttpUtility.UrlDecode(seriesTitle), seasonNumber, episodeNumber); var searchUrls = GetSearchUrls(GetQueryTitle(seriesTitle), seasonNumber, episodeNumber);
foreach (var url in searchUrls) foreach (var url in searchUrls)
{ {
@ -165,9 +169,13 @@ namespace NzbDrone.Core.Providers.Indexer
return CustomParser(item, episodeParseResult); return CustomParser(item, episodeParseResult);
} }
protected static string GetQueryTitle(string title) public static string GetQueryTitle(string title)
{ {
return title.Trim().Replace(' ', '+'); var cleanTitle = TitleSearchRegex.Replace(title, "+").Trim('+', ' ');
//remove any repeating +s
cleanTitle = Regex.Replace(cleanTitle, @"\+{1,100}", "+");
return cleanTitle;
} }
} }
} }

@ -1,33 +1,26 @@
@using NzbDrone.Web.Helpers; @using NzbDrone.Web.Helpers;
@model NzbDrone.Web.Models.QualityModel @model NzbDrone.Web.Models.QualityModel
@section HeaderContent{ @section HeaderContent{
<link rel="stylesheet" type="text/css" href="../../Content/Settings.css" /> <link rel="stylesheet" type="text/css" href="/Content/Settings.css" />
<link href="../../Content/QualitySettings.css" rel="stylesheet" type="text/css" /> <link href="/Content/QualitySettings.css" rel="stylesheet" type="text/css" />
<script src="../../Scripts/jquery-1.6.1.js" type="text/javascript"></script>
<script type="text/javascript">
</script>
} }
@section TitleContent{ @section TitleContent{
Settings Settings
} }
@section ActionMenu{ @section ActionMenu{
@{Html.RenderPartial("SubMenu");} @{Html.RenderPartial("SubMenu");}
} }
@section MainContent{ @section MainContent{
<div id="stylized"> <div id="stylized">
@using (Html.BeginForm("SaveQuality", "Settings", FormMethod.Post, new { id = "form", name = "form" })) @using (Html.BeginForm("SaveQuality", "Settings", FormMethod.Post, new { id = "form", name = "form" }))
{ {
<div id="top" class="settingsForm clearfix"> <div id="top" class="settingsForm clearfix">
<h1>Quality</h1> <h1>
<p></p> Quality</h1>
<p>
</p>
<label class="labelClass">@Html.LabelFor(m => m.DefaultQualityProfileId) <label class="labelClass">@Html.LabelFor(m => m.DefaultQualityProfileId)
<span class="small">@Html.DescriptionFor(m => m.DefaultQualityProfileId)</span> <span class="small">@Html.DescriptionFor(m => m.DefaultQualityProfileId)</span>
</label> </label>
@Html.DropDownListFor(m => m.DefaultQualityProfileId, Model.QualityProfileSelectList, new { @class = "inputClass" }) @Html.DropDownListFor(m => m.DefaultQualityProfileId, Model.QualityProfileSelectList, new { @class = "inputClass" })
</div> </div>
@ -36,9 +29,9 @@
<div id="profileContainer"> <div id="profileContainer">
<div id="profileHeader"> <div id="profileHeader">
<a id="addItem" href="@Url.Action("AddProfile", "Settings")"> <a id="addItem" href="@Url.Action("AddProfile", "Settings")">
<img src="../../Content/Images/Plus.png" alt="Add New Profile" width="20px" height="20px" /> Add New Profile</a> <img src="../../Content/Images/Plus.png" alt="Add New Profile" width="20px" height="20px" />
Add New Profile</a>
</div> </div>
<div id="profiles" class="clearfix"> <div id="profiles" class="clearfix">
@foreach (var item in Model.Profiles) @foreach (var item in Model.Profiles)
{ {
@ -46,21 +39,20 @@
} }
</div> </div>
</div> </div>
<button type="submit" id="save_button">
<button type="submit" id="save_button" >Save</button><img src="../../Content/Images/ajax-loader.gif" alt="Loader" id="saveAjax"/> Save</button><img src="../../Content/Images/ajax-loader.gif" alt="Loader" id="saveAjax" />
</div> </div>
} }
</div> </div>
<div id="result" class="hiddenResult">
<div id="result" class="hiddenResult"></div> </div>
} }
@section Scripts{ @section Scripts{
<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script> <script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js" type="text/javascript"></script> <script src="http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js"
type="text/javascript"></script>
<script src="../../Scripts/settingsForm.js" type="text/javascript"></script> <script src="../../Scripts/settingsForm.js" type="text/javascript"></script>
<script type="text/javascript"> <script type="text/javascript">
$("#addItem").live('click', function () { $("#addItem").live('click', function () {
$.ajax({ $.ajax({
@ -117,7 +109,7 @@
} }
}); });
} }
function getProfileId(obj) { function getProfileId(obj) {
var parentProfileSection = $(obj).parents('.profileSection'); var parentProfileSection = $(obj).parents('.profileSection');
return parentProfileSection.children('.qualityProfileId').val(); return parentProfileSection.children('.qualityProfileId').val();

Loading…
Cancel
Save