From b930eb099377f986a189a36ae9e870814567643a Mon Sep 17 00:00:00 2001
From: Mark McDowall <markus.mcd5@gmail.com>
Date: Fri, 4 May 2012 08:30:30 -0700
Subject: [PATCH] Newznab providers will be compared based on url, not name.

Built-in Newznab providers cannot be deleted (they would be re-added anyways), nor can the URL be changed.
---
 .../ProviderTests/NewznabProviderTest.cs      | 33 ++++++++++++++++---
 NzbDrone.Core/CentralDispatch.cs              |  4 +--
 .../Datastore/Migrations/Migration20120504.cs | 15 +++++++++
 NzbDrone.Core/NzbDrone.Core.csproj            |  3 +-
 ...{NewznzbProvider.cs => NewznabProvider.cs} | 14 ++++++--
 NzbDrone.Core/Repository/NewznabDefinition.cs |  2 ++
 .../Views/Settings/NewznabProvider.cshtml     | 22 ++++++++++---
 7 files changed, 79 insertions(+), 14 deletions(-)
 create mode 100644 NzbDrone.Core/Datastore/Migrations/Migration20120504.cs
 rename NzbDrone.Core/Providers/{NewznzbProvider.cs => NewznabProvider.cs} (86%)

diff --git a/NzbDrone.Core.Test/ProviderTests/NewznabProviderTest.cs b/NzbDrone.Core.Test/ProviderTests/NewznabProviderTest.cs
index 5dc19c2a5..94daaa82b 100644
--- a/NzbDrone.Core.Test/ProviderTests/NewznabProviderTest.cs
+++ b/NzbDrone.Core.Test/ProviderTests/NewznabProviderTest.cs
@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using FizzWare.NBuilder;
 using FluentAssertions;
@@ -216,6 +217,7 @@ namespace NzbDrone.Core.Test.ProviderTests
             //Assert
             var result = db.Fetch<NewznabDefinition>();
             result.Should().HaveCount(5);
+            result.Should().OnlyContain(i => i.BuiltIn);
         }
 
         [Test]
@@ -236,16 +238,39 @@ namespace NzbDrone.Core.Test.ProviderTests
             Mocker.SetConstant(db);
 
             db.Insert(definitions[0]);
-            db.Insert(definitions[1]);
+            db.Insert(definitions[2]);
 
             //Act
             Mocker.Resolve<NewznabProvider>().InitializeNewznabIndexers(definitions);
 
             //Assert
             var result = db.Fetch<NewznabDefinition>();
-            result.Should().HaveCount(5);
-            result.Where(d => d.Url == "http://www.nzbdrone.com").Should().HaveCount(3);
-            result.Where(d => d.Url == "http://www.nzbdrone2.com").Should().HaveCount(2);
+            result.Should().HaveCount(2);
+            result.Where(d => d.Url == "http://www.nzbdrone.com").Should().HaveCount(1);
+            result.Where(d => d.Url == "http://www.nzbdrone2.com").Should().HaveCount(1);
+        }
+
+        [Test]
+        public void InitializeNewznabIndexers_should_update_matching_indexer_to_be_builtin()
+        {
+            //Setup
+            var definition = Builder<NewznabDefinition>.CreateNew()
+                .With(d => d.Url = "http://www.nzbdrone2.com")
+                .With(d => d.BuiltIn = false)
+                .Build();
+
+            var db = TestDbHelper.GetEmptyDatabase();
+            Mocker.SetConstant(db);
+
+            db.Insert(definition);
+
+            //Act
+            Mocker.Resolve<NewznabProvider>().InitializeNewznabIndexers(new List<NewznabDefinition>{ definition });
+
+            //Assert
+            var result = db.Fetch<NewznabDefinition>();
+            result.Should().HaveCount(1);
+            result.First().BuiltIn.Should().BeTrue();
         }
     }
 }
\ No newline at end of file
diff --git a/NzbDrone.Core/CentralDispatch.cs b/NzbDrone.Core/CentralDispatch.cs
index e4e70e0b0..bd0db423e 100644
--- a/NzbDrone.Core/CentralDispatch.cs
+++ b/NzbDrone.Core/CentralDispatch.cs
@@ -107,8 +107,8 @@ namespace NzbDrone.Core
 
             var newznabIndexers = new List<NewznabDefinition>
                                       {
-                                              new NewznabDefinition { Enable = false, Name = "Nzbs.org", Url = "http://nzbs.org" },
-                                              new NewznabDefinition { Enable = false, Name = "Nzb.su", Url = "http://nzb.su" }
+                                              new NewznabDefinition { Enable = false, Name = "Nzbs.org", Url = "https://nzbs.org", BuiltIn = true },
+                                              new NewznabDefinition { Enable = false, Name = "Nzb.su", Url = "https://nzb.su", BuiltIn = true }
                                       };
 
             Kernel.Get<NewznabProvider>().InitializeNewznabIndexers(newznabIndexers);
diff --git a/NzbDrone.Core/Datastore/Migrations/Migration20120504.cs b/NzbDrone.Core/Datastore/Migrations/Migration20120504.cs
new file mode 100644
index 000000000..6cc851714
--- /dev/null
+++ b/NzbDrone.Core/Datastore/Migrations/Migration20120504.cs
@@ -0,0 +1,15 @@
+using System.Data;
+using Migrator.Framework;
+
+namespace NzbDrone.Core.Datastore.Migrations
+{
+
+    [Migration(20120504)]
+    public class Migration20120504 : NzbDroneMigration
+    {
+        protected override void MainDbUpgrade()
+        {
+            Database.AddColumn("NewznabDefinitions", "BuiltIn", DbType.Boolean, ColumnProperty.Null);
+        }
+    }
+}
\ No newline at end of file
diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj
index d635f1212..d77e6da71 100644
--- a/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/NzbDrone.Core/NzbDrone.Core.csproj
@@ -224,6 +224,7 @@
     <Compile Include="Datastore\MigrationLogger.cs" />
     <Compile Include="Datastore\MigrationsHelper.cs" />
     <Compile Include="Datastore\CustomeMapper.cs" />
+    <Compile Include="Datastore\Migrations\Migration20120504.cs" />
     <Compile Include="Datastore\Migrations\Migration20120430.cs" />
     <Compile Include="Datastore\Migrations\Migration20120420.cs" />
     <Compile Include="Datastore\Migrations\Migration20120228.cs" />
@@ -440,7 +441,7 @@
     <Compile Include="Providers\MisnamedProvider.cs">
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="Providers\NewznzbProvider.cs">
+    <Compile Include="Providers\NewznabProvider.cs">
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="Providers\NotificationProvider.cs">
diff --git a/NzbDrone.Core/Providers/NewznzbProvider.cs b/NzbDrone.Core/Providers/NewznabProvider.cs
similarity index 86%
rename from NzbDrone.Core/Providers/NewznzbProvider.cs
rename to NzbDrone.Core/Providers/NewznabProvider.cs
index c8dfaadbd..7f69b587c 100644
--- a/NzbDrone.Core/Providers/NewznzbProvider.cs
+++ b/NzbDrone.Core/Providers/NewznabProvider.cs
@@ -70,18 +70,28 @@ namespace NzbDrone.Core.Providers
             foreach (var feedProvider in indexers)
             {
                 NewznabDefinition indexerLocal = feedProvider;
-                if (!currentIndexers.Exists(c => c.Name == indexerLocal.Name))
+                var currentIndexer = currentIndexers
+                                        .SingleOrDefault(c => new Uri(c.Url.ToLower()).Host == new Uri(indexerLocal.Url.ToLower()).Host);
+
+                if (currentIndexer == null)
                 {
                     var settings = new NewznabDefinition
                                        {
                                            Enable = false,
                                            Name = indexerLocal.Name,
                                            Url = indexerLocal.Url,
-                                           ApiKey = indexerLocal.ApiKey
+                                           ApiKey = indexerLocal.ApiKey,
+                                           BuiltIn = true
                                        };
 
                     Save(settings);
                 }
+
+                else
+                {
+                    currentIndexer.BuiltIn = true;
+                    Save(currentIndexer);
+                }
             }
         }
 
diff --git a/NzbDrone.Core/Repository/NewznabDefinition.cs b/NzbDrone.Core/Repository/NewznabDefinition.cs
index a197be4ad..3e658d902 100644
--- a/NzbDrone.Core/Repository/NewznabDefinition.cs
+++ b/NzbDrone.Core/Repository/NewznabDefinition.cs
@@ -16,5 +16,7 @@ namespace NzbDrone.Core.Repository
         public String Url { get; set; }
 
         public String ApiKey { get; set; }
+
+        public bool BuiltIn { get; set; }
     }
 }
\ No newline at end of file
diff --git a/NzbDrone.Web/Views/Settings/NewznabProvider.cshtml b/NzbDrone.Web/Views/Settings/NewznabProvider.cshtml
index 6d9ae677e..b37ac4f5e 100644
--- a/NzbDrone.Web/Views/Settings/NewznabProvider.cshtml
+++ b/NzbDrone.Web/Views/Settings/NewznabProvider.cshtml
@@ -13,8 +13,11 @@
             <span class="titleText" id="title_@(Model.Id)">
                 @Model.Name
             </span>
-            <a href="#" id="@Model.Id" class="deleteProvider" onclick="deleteProvider('@(Model.Id)'); return false;">
-                <img src="../../Content/Images/close.png" alt="Delete" width="22px" height="22px" /></a>
+            @if(!Model.BuiltIn)
+            {
+                <a href="#" id="@Model.Id" class="deleteProvider" onclick="deleteProvider('@(Model.Id)'); return false;">
+                    <img src="../../Content/Images/close.png" alt="Delete" width="22px" height="22px" /></a>
+            }
         </div>
         <div class="providerOptions">
             @Html.Label("Enabled")
@@ -22,9 +25,18 @@
 
             @Html.LabelFor(x => x.Name)
             @Html.TextBoxFor(x => x.Name, new {@class = "providerName_textbox"})
-
-            @Html.LabelFor(x => x.Url)
-            @Html.TextBoxFor(m => m.Url)
+            
+            @if(!Model.BuiltIn)
+            {
+                @Html.LabelFor(x => x.Url)
+                @Html.TextBoxFor(m => m.Url)
+            }
+            
+            else
+            {
+                @Html.LabelFor(x => x.Url)
+                @Html.TextBoxFor(m => m.Url, new { disabled = "disabled" })
+            }
 
             @Html.LabelFor(x => x.ApiKey)
             @Html.TextBoxFor(m => m.ApiKey)