extracted interface fom HttpProvider

pull/23/head
Keivan Beigi 12 years ago
parent 35e2e83595
commit 1465fbf499

@ -11,7 +11,7 @@ namespace NzbDrone.Common.Test
[Test]
public void DownloadString_should_be_able_to_dowload_text_file()
{
var jquery = new HttpProvider().DownloadString("http://www.google.com/robots.txt");
var jquery = new HttpProvider(new EnvironmentProvider()).DownloadString("http://www.google.com/robots.txt");
jquery.Should().NotBeBlank();
jquery.Should().Contain("Sitemap");
@ -23,7 +23,7 @@ namespace NzbDrone.Common.Test
[ExpectedException]
public void DownloadString_should_throw_on_error(string url)
{
var jquery = new HttpProvider().DownloadString(url);
var jquery = new HttpProvider(new EnvironmentProvider()).DownloadString(url);
}
}
}

@ -1,5 +1,4 @@
using System.Linq;
using System;
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
@ -8,7 +7,17 @@ using NLog;
namespace NzbDrone.Common
{
public class HttpProvider
public interface IHttpProvider
{
string DownloadString(string address);
string DownloadString(string address, string username, string password);
string DownloadString(string address, ICredentials identity);
Stream DownloadStream(string url, NetworkCredential credential = null);
void DownloadFile(string url, string fileName);
string PostCommand(string address, string username, string password, string command);
}
public class HttpProvider : IHttpProvider
{
private readonly EnvironmentProvider _environmentProvider;
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
@ -20,21 +29,17 @@ namespace NzbDrone.Common
_userAgent = String.Format("NzbDrone {0}", _environmentProvider.Version);
}
public HttpProvider()
{
}
public virtual string DownloadString(string address)
public string DownloadString(string address)
{
return DownloadString(address, null);
}
public virtual string DownloadString(string address, string username, string password)
public string DownloadString(string address, string username, string password)
{
return DownloadString(address, new NetworkCredential(username, password));
}
public virtual string DownloadString(string address, ICredentials identity)
public string DownloadString(string address, ICredentials identity)
{
try
{
@ -49,7 +54,7 @@ namespace NzbDrone.Common
}
}
public virtual Stream DownloadStream(string url, NetworkCredential credential = null)
public Stream DownloadStream(string url, NetworkCredential credential = null)
{
var request = (HttpWebRequest)WebRequest.Create(url);
request.UserAgent = _userAgent;
@ -60,7 +65,7 @@ namespace NzbDrone.Common
return response.GetResponseStream();
}
public virtual void DownloadFile(string url, string fileName)
public void DownloadFile(string url, string fileName)
{
try
{
@ -87,7 +92,7 @@ namespace NzbDrone.Common
}
}
public virtual string PostCommand(string address, string username, string password, string command)
public string PostCommand(string address, string username, string password, string command)
{
address = String.Format("http://{0}/jsonrpc", address);

@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene
[Test]
public void fetch_should_return_list_of_mappings()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString(SCENE_MAPPING_URL))
.Returns(ReadAllText("Files", "SceneMappings.json"));
@ -43,7 +43,7 @@ namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene
[Test]
public void should_throw_on_server_error()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString(SCENE_MAPPING_URL))
.Throws(new WebException());
Assert.Throws<WebException>(() => Subject.Fetch());
@ -52,7 +52,7 @@ namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene
[Test]
public void should_throw_on_bad_json()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString(SCENE_MAPPING_URL))
.Returns("bad json");
Assert.Throws<JsonReaderException>(() => Subject.Fetch());

@ -33,7 +33,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
private void WithFailedDownload()
{
Mocker.GetMock<HttpProvider>().Setup(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>())).Throws(new WebException());
Mocker.GetMock<IHttpProvider>().Setup(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>())).Throws(new WebException());
}
[Test]
@ -41,7 +41,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
{
Subject.DownloadNzb(nzbUrl, title, false).Should().BeTrue();
Mocker.GetMock<HttpProvider>().Verify(c => c.DownloadFile(nzbUrl, nzbPath), Times.Once());
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(nzbUrl, nzbPath), Times.Once());
}
[Test]
@ -51,7 +51,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
Subject.DownloadNzb(nzbUrl, title, false).Should().BeTrue();
Mocker.GetMock<HttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
}
[Test]
@ -72,7 +72,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
Subject.DownloadNzb(nzbUrl, illegalTitle, false).Should().BeTrue();
Mocker.GetMock<HttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), expectedFilename), Times.Once());
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), expectedFilename), Times.Once());
}
}
}

@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
private void WithFailResponse()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.PostCommand("192.168.5.55:6789", "nzbget", "pass", It.IsAny<String>()))
.Returns(ReadAllText("Files", "Nzbget", "JsonError.txt"));
}
@ -38,7 +38,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
const string url = "http://www.nzbdrone.com";
const string title = "30 Rock - S01E01 - Pilot [HDTV-720p]";
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.PostCommand("192.168.5.55:6789", "nzbget", "pass",
It.Is<String>(c => c.Equals("{\"method\":\"appendurl\",\"params\":[\"30 Rock - S01E01 - Pilot [HDTV-720p]\",\"TV\",0,false,\"http://www.nzbdrone.com\"]}"))))
.Returns("{\"version\": \"1.1\",\"result\": true}");

@ -26,21 +26,21 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetProviderTests
private void WithFullQueue()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.PostCommand("192.168.5.55:6789", "nzbget", "pass", It.IsAny<String>()))
.Returns(ReadAllText("Files", "Nzbget", "Queue.txt"));
}
private void WithEmptyQueue()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.PostCommand("192.168.5.55:6789", "nzbget", "pass", It.IsAny<String>()))
.Returns(ReadAllText("Files", "Nzbget", "Queue_empty.txt"));
}
private void WithFailResponse()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.PostCommand("192.168.5.55:6789", "nzbget", "pass", It.IsAny<String>()))
.Returns(ReadAllText("Files", "Nzbget", "JsonError.txt"));
}

@ -36,7 +36,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
private void WithFailedDownload()
{
Mocker.GetMock<HttpProvider>().Setup(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>())).Throws(new WebException());
Mocker.GetMock<IHttpProvider>().Setup(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>())).Throws(new WebException());
}
[Test]
@ -44,7 +44,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
{
Mocker.Resolve<PneumaticProvider>().DownloadNzb(nzbUrl, title, false).Should().BeTrue();
Mocker.GetMock<HttpProvider>().Verify(c => c.DownloadFile(nzbUrl, nzbPath),Times.Once());
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(nzbUrl, nzbPath),Times.Once());
}
[Test]
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
Mocker.Resolve<PneumaticProvider>().DownloadNzb(nzbUrl, title, false).Should().BeTrue();
Mocker.GetMock<HttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never());
}
[Test]
@ -81,7 +81,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
Mocker.Resolve<PneumaticProvider>().DownloadNzb(nzbUrl, illegalTitle, false).Should().BeTrue();
Mocker.GetMock<HttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), expectedFilename), Times.Once());
Mocker.GetMock<IHttpProvider>().Verify(c => c.DownloadFile(It.IsAny<string>(), expectedFilename), Times.Once());
}
}
}

@ -41,7 +41,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
private void WithFullQueue()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(
s =>
s.DownloadString(
@ -51,20 +51,20 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
private void WithEmptyQueue()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=queue&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
.Returns(ReadAllText("Files","QueueEmpty.txt"));
}
private void WithFailResponse()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString(It.IsAny<String>())).Returns(ReadAllText("Files","JsonError.txt"));
}
private void WithUnknownPriorityQueue()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(
s =>
s.DownloadString(

@ -33,14 +33,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
private void WithFailResponse()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString(It.IsAny<String>())).Returns("{ \"status\": false, \"error\": \"API Key Required\" }");
}
[Test]
public void add_url_should_format_request_properly()
{
Mocker.GetMock<HttpProvider>(MockBehavior.Strict)
Mocker.GetMock<IHttpProvider>(MockBehavior.Strict)
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=0&pp=3&cat=tv&nzbname=My+Series+Name+-+5x2-5x3+-+My+title+%5bBluray720p%5d+%5bProper%5d&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
.Returns("{ \"status\": true }");
@ -70,7 +70,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
Mocker.GetMock<HttpProvider>(MockBehavior.Strict)
Mocker.GetMock<IHttpProvider>(MockBehavior.Strict)
.Setup(s => s.DownloadString("http://192.168.5.22:1111/api?mode=get_cats&output=json&apikey=5c770e3197e4fe763423ee7c392c25d2&ma_username=admin2&ma_password=pass2"))
.Returns(ReadAllText("Files","Categories_json.txt"));
@ -85,7 +85,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
[Test]
public void should_be_able_to_get_categories_using_config()
{
Mocker.GetMock<HttpProvider>(MockBehavior.Strict)
Mocker.GetMock<IHttpProvider>(MockBehavior.Strict)
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=get_cats&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
.Returns(ReadAllText("Files","Categories_json.txt"));
@ -100,7 +100,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
[Test]
public void GetHistory_should_return_a_list_with_items_when_the_history_has_items()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=history&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
.Returns(ReadAllText("Files", "History.txt"));
@ -114,7 +114,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
[Test]
public void GetHistory_should_return_an_empty_list_when_the_queue_is_empty()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=history&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
.Returns(ReadAllText("Files","HistoryEmpty.txt"));
@ -128,7 +128,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
[Test]
public void GetHistory_should_return_an_empty_list_when_there_is_an_error_getting_the_queue()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=history&output=json&start=0&limit=0&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
.Returns(ReadAllText("Files","JsonError.txt"));
@ -141,7 +141,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
var response = "{ \"version\": \"0.6.9\" }";
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=version&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
.Returns(response);
@ -158,7 +158,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
var response = "{ \"version\": \"0.6.9\" }";
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=version&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
.Returns(response);
@ -175,7 +175,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
{
var response = "{ \"version\": \"0.6.9\" }";
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=version&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
.Returns(response);
@ -189,7 +189,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
[Test]
public void should_return_false_when_WebException_is_thrown()
{
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString(It.IsAny<String>())).Throws(new WebException());
Mocker.Resolve<SabProvider>().DownloadNzb(url, title, false).Should().BeFalse();
@ -207,14 +207,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.SetupGet(s => s.SabBacklogTvPriority)
.Returns(SabPriorityType.Low);
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=1&pp=3&cat=tv&nzbname=My+Series+Name+-+5x2-5x3+-+My+title+%5bBluray720p%5d+%5bProper%5d&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
.Returns("{ \"status\": true }");
Mocker.Resolve<SabProvider>().DownloadNzb(url, title, true).Should().BeTrue();
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Verify(v => v.DownloadString("http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=1&pp=3&cat=tv&nzbname=My+Series+Name+-+5x2-5x3+-+My+title+%5bBluray720p%5d+%5bProper%5d&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"), Times.Once());
}
@ -229,14 +229,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabProviderTests
.SetupGet(s => s.SabBacklogTvPriority)
.Returns(SabPriorityType.Low);
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Setup(s => s.DownloadString("http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=-1&pp=3&cat=tv&nzbname=My+Series+Name+-+5x2-5x3+-+My+title+%5bBluray720p%5d+%5bProper%5d&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"))
.Returns("{ \"status\": true }");
Mocker.Resolve<SabProvider>().DownloadNzb(url, title, false).Should().BeTrue();
Mocker.GetMock<HttpProvider>()
Mocker.GetMock<IHttpProvider>()
.Verify(v => v.DownloadString("http://192.168.5.55:2222/api?mode=addurl&name=http://www.nzbclub.com/nzb_download.aspx?mid=1950232&priority=-1&pp=3&cat=tv&nzbname=My+Series+Name+-+5x2-5x3+-+My+title+%5bBluray720p%5d+%5bProper%5d&output=json&apikey=5c770e3197e4fe763423ee7c392c25d1&ma_username=admin&ma_password=pass"), Times.Once());
}
}

@ -73,7 +73,7 @@ namespace NzbDrone.Core.Test.JobTests
StartUpdate();
Mocker.GetMock<HttpProvider>().Verify(
Mocker.GetMock<IHttpProvider>().Verify(
c => c.DownloadFile(updatePackage.Url, updateArchive));
}

@ -1,10 +1,7 @@
using System.Linq;
using NUnit.Framework;
using NUnit.Framework;
using NzbDrone.Common;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Tv.Events;
namespace NzbDrone.Core.Test.MediaCoverTests
{
@ -14,7 +11,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
[SetUp]
public void Setup()
{
Mocker.SetConstant(new HttpProvider());
Mocker.SetConstant(new HttpProvider(new EnvironmentProvider()));
Mocker.SetConstant(new DiskProvider());
Mocker.SetConstant(new EnvironmentProvider());
}

@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.ProviderTests
var response = "<MediaContainer size=\"1\" mediaTagPrefix=\"/system/bundle/media/flags/\" mediaTagVersion=\"1329809559\" title1=\"Plex Library\" identifier=\"com.plexapp.plugins.library\"><Directory refreshing=\"0\" key=\"5\" type=\"show\" title=\"TV Shows\" art=\"/:/resources/show-fanart.jpg\" agent=\"com.plexapp.agents.thetvdb\" scanner=\"Plex Series Scanner\" language=\"en\" updatedAt=\"1329810350\"><Location path=\"C:/Test/TV\"/></Directory></MediaContainer>";
Stream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes(response));
Mocker.GetMock<HttpProvider>().Setup(s => s.DownloadStream("http://localhost:32400/library/sections", null))
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadStream("http://localhost:32400/library/sections", null))
.Returns(stream);
@ -73,7 +73,7 @@ namespace NzbDrone.Core.Test.ProviderTests
var response = "<MediaContainer size=\"1\" mediaTagPrefix=\"/system/bundle/media/flags/\" mediaTagVersion=\"1329809559\" title1=\"Plex Library\" identifier=\"com.plexapp.plugins.library\"><Directory refreshing=\"0\" key=\"5\" type=\"show\" title=\"TV Shows\" art=\"/:/resources/show-fanart.jpg\" agent=\"com.plexapp.agents.thetvdb\" scanner=\"Plex Series Scanner\" language=\"en\" updatedAt=\"1329810350\"><Location path=\"C:/Test/TV\"/></Directory><Directory refreshing=\"0\" key=\"7\" type=\"movie\" title=\"TV Shows\" art=\"/:/resources/show-fanart.jpg\" agent=\"com.plexapp.agents.thetvdb\" scanner=\"Plex Series Scanner\" language=\"en\" updatedAt=\"1329810350\"><Location path=\"C:/Test/TV\"/></Directory></MediaContainer>";
Stream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes(response));
Mocker.GetMock<HttpProvider>().Setup(s => s.DownloadStream("http://localhost:32400/library/sections", null))
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadStream("http://localhost:32400/library/sections", null))
.Returns(stream);
@ -92,7 +92,7 @@ namespace NzbDrone.Core.Test.ProviderTests
var response = "<MediaContainer size=\"1\" mediaTagPrefix=\"/system/bundle/media/flags/\" mediaTagVersion=\"1329809559\" title1=\"Plex Library\" identifier=\"com.plexapp.plugins.library\"><Directory refreshing=\"0\" key=\"5\" type=\"show\" title=\"TV Shows\" art=\"/:/resources/show-fanart.jpg\" agent=\"com.plexapp.agents.thetvdb\" scanner=\"Plex Series Scanner\" language=\"en\" updatedAt=\"1329810350\"><Location path=\"C:/Test/TV\"/></Directory><Directory refreshing=\"0\" key=\"6\" type=\"show\" title=\"TV Shows\" art=\"/:/resources/show-fanart.jpg\" agent=\"com.plexapp.agents.thetvdb\" scanner=\"Plex Series Scanner\" language=\"en\" updatedAt=\"1329810350\"><Location path=\"C:/Test/TV\"/></Directory></MediaContainer>";
Stream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes(response));
Mocker.GetMock<HttpProvider>().Setup(s => s.DownloadStream("http://localhost:32400/library/sections", null))
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadStream("http://localhost:32400/library/sections", null))
.Returns(stream);
@ -112,7 +112,7 @@ namespace NzbDrone.Core.Test.ProviderTests
var response = "";
Stream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes(response));
Mocker.GetMock<HttpProvider>().Setup(s => s.DownloadString("http://localhost:32400/library/sections/5/refresh"))
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadString("http://localhost:32400/library/sections/5/refresh"))
.Returns(response);
@ -133,7 +133,7 @@ namespace NzbDrone.Core.Test.ProviderTests
var expectedUrl = String.Format("http://localhost:3000/xbmcCmds/xbmcHttp?command=ExecBuiltIn(Notification({0}, {1}))", header, message);
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.DownloadString(expectedUrl))
.Returns("ok");
@ -153,7 +153,7 @@ namespace NzbDrone.Core.Test.ProviderTests
const string header = "Test Header";
const string message = "Test Message";
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.DownloadString(It.IsAny<string>()))
.Returns("ok");
@ -176,7 +176,7 @@ namespace NzbDrone.Core.Test.ProviderTests
var expectedUrl = String.Format("http://localhost:3000/xbmcCmds/xbmcHttp?command=ExecBuiltIn(Notification({0}, {1}))", header, message);
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.DownloadString(expectedUrl, "plex", "plex"))
.Returns("ok");
@ -197,7 +197,7 @@ namespace NzbDrone.Core.Test.ProviderTests
const string header = "Test Header";
const string message = "Test Message";
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.DownloadString(It.IsAny<string>(), "plex", "plex"))
.Returns("ok");

@ -98,7 +98,7 @@ namespace NzbDrone.Core.Test.ProviderTests
{
var message = "{\"id\":10,\"jsonrpc\":\"2.0\",\"result\":{\"version\":" + number + "}}";
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand("localhost:8080", "xbmc", "xbmc", It.IsAny<string>()))
.Returns(message);
@ -118,7 +118,7 @@ namespace NzbDrone.Core.Test.ProviderTests
{
var message = "{\"id\":10,\"jsonrpc\":\"2.0\",\"result\":{\"version\":{\"major\":" + major + ",\"minor\":" + minor + ",\"patch\":" + patch + "}}}";
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand("localhost:8080", "xbmc", "xbmc", It.IsAny<string>()))
.Returns(message);
@ -134,7 +134,7 @@ namespace NzbDrone.Core.Test.ProviderTests
{
var message = "{\"error\":{\"code\":-32601,\"message\":\"Method not found.\"},\"id\":10,\"jsonrpc\":\"2.0\"}";
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand("localhost:8080", "xbmc", "xbmc", It.IsAny<string>()))
.Returns(message);
@ -164,7 +164,7 @@ namespace NzbDrone.Core.Test.ProviderTests
+ video.ToString().ToLower()
+ "}}";
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand("localhost:8080", "xbmc", "xbmc", It.IsAny<string>()))
.Returns(message);
@ -183,7 +183,7 @@ namespace NzbDrone.Core.Test.ProviderTests
WithNoActivePlayers();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand("localhost:8080", "xbmc", "xbmc", It.IsAny<string>()))
.Returns(EdenActivePlayers);
@ -200,7 +200,7 @@ namespace NzbDrone.Core.Test.ProviderTests
WithVideoPlayerActive();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand("localhost:8080", "xbmc", "xbmc", It.IsAny<string>()))
.Returns(EdenActivePlayers);
@ -218,7 +218,7 @@ namespace NzbDrone.Core.Test.ProviderTests
WithAudioPlayerActive();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand("localhost:8080", "xbmc", "xbmc", It.IsAny<string>()))
.Returns(EdenActivePlayers);
@ -236,7 +236,7 @@ namespace NzbDrone.Core.Test.ProviderTests
WithPicturePlayerActive();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand("localhost:8080", "xbmc", "xbmc", It.IsAny<string>()))
.Returns(EdenActivePlayers);
@ -254,7 +254,7 @@ namespace NzbDrone.Core.Test.ProviderTests
WithAllPlayersActive();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand("localhost:8080", "xbmc", "xbmc", It.IsAny<string>()))
.Returns(EdenActivePlayers);
@ -275,7 +275,7 @@ namespace NzbDrone.Core.Test.ProviderTests
var message = "{\"id\":10,\"jsonrpc\":\"2.0\",\"result\":{\"limits\":{\"end\":5,\"start\":0,\"total\":5},\"tvshows\":[{\"file\":\"smb://HOMESERVER/TV/7th Heaven/\",\"imdbnumber\":\"73928\",\"label\":\"7th Heaven\",\"tvshowid\":3},{\"file\":\"smb://HOMESERVER/TV/8 Simple Rules/\",\"imdbnumber\":\"78461\",\"label\":\"8 Simple Rules\",\"tvshowid\":4},{\"file\":\"smb://HOMESERVER/TV/24-7 Penguins-Capitals- Road to the NHL Winter Classic/\",\"imdbnumber\":\"213041\",\"label\":\"24/7 Penguins/Capitals: Road to the NHL Winter Classic\",\"tvshowid\":1},{\"file\":\"smb://HOMESERVER/TV/30 Rock/\",\"imdbnumber\":\"79488\",\"label\":\"30 Rock\",\"tvshowid\":2},{\"file\":\"smb://HOMESERVER/TV/90210/\",\"imdbnumber\":\"82716\",\"label\":\"90210\",\"tvshowid\":5}]}}";
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand("localhost:8080", "xbmc", "xbmc", It.IsAny<string>()))
.Returns(message);
@ -324,7 +324,7 @@ namespace NzbDrone.Core.Test.ProviderTests
var url = String.Format("http://localhost:8080/xbmcCmds/xbmcHttp?command=ExecBuiltIn(CleanLibrary(video))");
//var fakeUdpProvider = Mocker.GetMock<EventClient>();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.DownloadString(url, username, password)).Returns("Ok\n");
@ -353,7 +353,7 @@ namespace NzbDrone.Core.Test.ProviderTests
//var fakeUdpProvider = Mocker.GetMock<EventClient>();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.DownloadString(setResponseUrl, username, password)).Returns("<xml><tag>OK</xml>");
fakeHttp.Setup(s => s.DownloadString(resetResponseUrl, username, password)).Returns(@"<html>
<li>OK
@ -386,7 +386,7 @@ namespace NzbDrone.Core.Test.ProviderTests
//var fakeUdpProvider = Mocker.GetMock<EventClient>();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.DownloadString(setResponseUrl, username, password)).Returns("<xml><tag>OK</xml>");
fakeHttp.Setup(s => s.DownloadString(resetResponseUrl, username, password)).Returns(@"<html>
<li>OK
@ -419,7 +419,7 @@ namespace NzbDrone.Core.Test.ProviderTests
//var fakeUdpProvider = Mocker.GetMock<EventClient>();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.DownloadString(setResponseUrl, username, password)).Returns("<xml><tag>OK</xml>");
fakeHttp.Setup(s => s.DownloadString(resetResponseUrl, username, password)).Returns(@"<html>
<li>OK
@ -468,7 +468,7 @@ namespace NzbDrone.Core.Test.ProviderTests
.With(s => s.Title = "30 Rock")
.Build();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.DownloadString(queryUrl, username, password)).Returns(queryResult);
fakeHttp.Setup(s => s.DownloadString(url, username, password));
@ -494,7 +494,7 @@ namespace NzbDrone.Core.Test.ProviderTests
.With(s => s.Title = "30 Rock")
.Build();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.DownloadString(queryUrl, username, password)).Returns(queryResult);
fakeHttp.Setup(s => s.DownloadString(url, username, password));
@ -522,7 +522,7 @@ namespace NzbDrone.Core.Test.ProviderTests
.With(s => s.Title = "30 Rock")
.Build();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand(host, username, password, It.Is<string>(e => e.Replace(" ", "").Replace("\r\n", "").Replace("\t", "") == expectedJson.Replace(" ", ""))))
.Returns(tvshows);
@ -555,7 +555,7 @@ namespace NzbDrone.Core.Test.ProviderTests
.With(s => s.Title = "30 Rock")
.Build();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand(host, username, password, It.Is<string>(e => e.Replace(" ", "").Replace("\r\n", "").Replace("\t", "") == expectedJson.Replace(" ", ""))))
.Returns(tvshows);
@ -588,7 +588,7 @@ namespace NzbDrone.Core.Test.ProviderTests
.With(s => s.Title = "30 Rock")
.Build();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand(host, username, password, It.Is<string>(e => e.Replace(" ", "").Replace("\r\n", "").Replace("\t", "") == expectedJson.Replace(" ", ""))))
.Returns(tvshows);
@ -620,7 +620,7 @@ namespace NzbDrone.Core.Test.ProviderTests
.With(s => s.Title = "30 Rock")
.Build();
var fakeHttp = Mocker.GetMock<HttpProvider>();
var fakeHttp = Mocker.GetMock<IHttpProvider>();
fakeHttp.Setup(s => s.PostCommand(host, username, password, It.Is<string>(e => e.Replace(" ", "").Replace("\r\n", "").Replace("\t", "") == expectedJson.Replace(" ", ""))))
.Returns(tvshows);

@ -22,19 +22,19 @@ namespace NzbDrone.Core.Test.ProviderTests.XemCommunicationProviderTests
{
private void WithFailureJson()
{
Mocker.GetMock<HttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
.Returns(ReadAllText("Files","Xem","Failure.txt"));
}
private void WithIdsJson()
{
Mocker.GetMock<HttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
.Returns(ReadAllText("Files","Xem","Ids.txt"));
}
private void WithMappingsJson()
{
Mocker.GetMock<HttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
.Returns(ReadAllText("Files","Xem","Mappings.txt"));
}

@ -22,19 +22,19 @@ namespace NzbDrone.Core.Test.ProviderTests.XemCommunicationProviderTests
{
private void WithFailureJson()
{
Mocker.GetMock<HttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
.Returns(ReadAllText("Files", "Xem", "Failure.txt"));
}
private void WithIdsJson()
{
Mocker.GetMock<HttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
.Returns(ReadAllText("Files", "Xem", "Ids.txt"));
}
private void WithMappingsJson()
{
Mocker.GetMock<HttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
Mocker.GetMock<IHttpProvider>().Setup(s => s.DownloadString(It.IsAny<String>()))
.Returns(ReadAllText("Files", "Xem", "Mappings.txt"));
}

@ -15,11 +15,11 @@ namespace NzbDrone.Core.DataAugmentation.DailySeries
public class DailySeriesDataProxy : IDailySeriesDataProxy
{
private readonly HttpProvider _httpProvider;
private readonly IHttpProvider _httpProvider;
private readonly IConfigService _configService;
private readonly Logger _logger;
public DailySeriesDataProxy(HttpProvider httpProvider, IConfigService configService, Logger logger)
public DailySeriesDataProxy(IHttpProvider httpProvider, IConfigService configService, Logger logger)
{
_httpProvider = httpProvider;
_configService = configService;

@ -12,10 +12,10 @@ namespace NzbDrone.Core.DataAugmentation.Scene
public class SceneMappingProxy : ISceneMappingProxy
{
private readonly HttpProvider _httpProvider;
private readonly IHttpProvider _httpProvider;
private readonly IConfigService _configService;
public SceneMappingProxy(HttpProvider httpProvider, IConfigService configService)
public SceneMappingProxy(IHttpProvider httpProvider, IConfigService configService)
{
_httpProvider = httpProvider;
_configService = configService;

@ -12,13 +12,13 @@ namespace NzbDrone.Core.Download.Clients
public class BlackholeProvider : IDownloadClient
{
private readonly IConfigService _configService;
private readonly HttpProvider _httpProvider;
private readonly IHttpProvider _httpProvider;
private readonly DiskProvider _diskProvider;
private readonly UpgradeHistorySpecification _upgradeHistorySpecification;
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public BlackholeProvider(IConfigService configService, HttpProvider httpProvider,
public BlackholeProvider(IConfigService configService, IHttpProvider httpProvider,
DiskProvider diskProvider, UpgradeHistorySpecification upgradeHistorySpecification)
{
_configService = configService;

@ -13,14 +13,15 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
{
public class NzbgetProvider : IDownloadClient
{
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
private readonly IConfigService _configService;
private readonly HttpProvider _httpProvider;
private readonly IHttpProvider _httpProvider;
private readonly Logger _logger;
public NzbgetProvider(IConfigService configService, HttpProvider httpProvider)
public NzbgetProvider(IConfigService configService, IHttpProvider httpProvider, Logger logger)
{
_configService = configService;
_httpProvider = httpProvider;
_logger = logger;
}
public NzbgetProvider()
@ -55,7 +56,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
catch (Exception ex)
{
logger.WarnException("Unable to connect to Nzbget to check queue.", ex);
_logger.WarnException("Unable to connect to Nzbget to check queue.", ex);
return false;
}
}
@ -73,20 +74,20 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
Params = new object[]{ title, cat, priority, false, url }
};
logger.Info("Adding report [{0}] to the queue.", title);
_logger.Info("Adding report [{0}] to the queue.", title);
var response = PostCommand(JsonConvert.SerializeObject(command));
CheckForError(response);
var success = JsonConvert.DeserializeObject<EnqueueResponse>(response).Result;
logger.Debug("Queue Response: [{0}]", success);
_logger.Debug("Queue Response: [{0}]", success);
return true;
}
catch (WebException ex)
{
logger.Error("Error communicating with Nzbget: " + ex.Message);
_logger.Error("Error communicating with Nzbget: " + ex.Message);
}
return false;
@ -145,7 +146,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
}
catch(Exception ex)
{
logger.DebugException("Failed to Test Nzbget", ex);
_logger.DebugException("Failed to Test Nzbget", ex);
}
return String.Empty;

@ -15,12 +15,12 @@ namespace NzbDrone.Core.Download.Clients
public class PneumaticProvider : IDownloadClient
{
private readonly IConfigService _configService;
private readonly HttpProvider _httpProvider;
private readonly IHttpProvider _httpProvider;
private readonly DiskProvider _diskProvider;
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public PneumaticProvider(IConfigService configService, HttpProvider httpProvider,
public PneumaticProvider(IConfigService configService, IHttpProvider httpProvider,
DiskProvider diskProvider)
{
_configService = configService;

@ -19,9 +19,9 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
{
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
private readonly IConfigService _configService;
private readonly HttpProvider _httpProvider;
private readonly IHttpProvider _httpProvider;
public SabProvider(IConfigService configService, HttpProvider httpProvider)
public SabProvider(IConfigService configService, IHttpProvider httpProvider)
{
_configService = configService;
_httpProvider = httpProvider;

@ -10,11 +10,11 @@ namespace NzbDrone.Core.ExternalNotification
{
public class PlexProvider
{
private readonly HttpProvider _httpProvider;
private readonly IHttpProvider _httpProvider;
private readonly IConfigService _configService;
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public PlexProvider(HttpProvider httpProvider, IConfigService configService)
public PlexProvider(IHttpProvider httpProvider, IConfigService configService)
{
_httpProvider = httpProvider;
_configService = configService;

@ -21,10 +21,10 @@ namespace NzbDrone.Core.Indexers
public class FetchFeedService : IFetchFeedFromIndexers
{
private readonly Logger _logger;
private readonly HttpProvider _httpProvider;
private readonly IHttpProvider _httpProvider;
protected FetchFeedService(HttpProvider httpProvider, Logger logger)
public FetchFeedService(IHttpProvider httpProvider, Logger logger)
{
_httpProvider = httpProvider;
_logger = logger;

@ -15,7 +15,7 @@ namespace NzbDrone.Core.Lifecycle
private readonly UpdateProvider _updateProvider;
private readonly EnvironmentProvider _environmentProvider;
private readonly DiskProvider _diskProvider;
private readonly HttpProvider _httpProvider;
private readonly IHttpProvider _httpProvider;
private readonly ProcessProvider _processProvider;
private readonly ArchiveProvider _archiveProvider;
private readonly ConfigFileProvider _configFileProvider;

@ -12,13 +12,13 @@ namespace NzbDrone.Core.MediaCover
IHandleAsync<SeriesUpdatedEvent>,
IHandleAsync<SeriesDeletedEvent>
{
private readonly HttpProvider _httpProvider;
private readonly IHttpProvider _httpProvider;
private readonly DiskProvider _diskProvider;
private readonly Logger _logger;
private readonly string _coverRootFolder;
public MediaCoverService(HttpProvider httpProvider, DiskProvider diskProvider, EnvironmentProvider environmentProvider, Logger logger)
public MediaCoverService(IHttpProvider httpProvider, DiskProvider diskProvider, EnvironmentProvider environmentProvider, Logger logger)
{
_httpProvider = httpProvider;
_diskProvider = diskProvider;

@ -15,7 +15,7 @@ namespace NzbDrone.Core.Providers
{
public class UpdateProvider
{
private readonly HttpProvider _httpProvider;
private readonly IHttpProvider _httpProvider;
private readonly IConfigService _configService;
private readonly EnvironmentProvider _environmentProvider;
@ -26,7 +26,7 @@ namespace NzbDrone.Core.Providers
public const string DEFAULT_UPDATE_URL = @"http://update.nzbdrone.com/_release/";
public UpdateProvider(HttpProvider httpProvider, IConfigService configService,
public UpdateProvider(IHttpProvider httpProvider, IConfigService configService,
EnvironmentProvider environmentProvider, DiskProvider diskProvider)
{
_httpProvider = httpProvider;

@ -18,10 +18,10 @@ namespace NzbDrone.Core.Providers
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly IConfigService _configService;
private readonly HttpProvider _httpProvider;
private readonly IHttpProvider _httpProvider;
private readonly EventClientProvider _eventClientProvider;
public XbmcProvider(IConfigService configService, HttpProvider httpProvider, EventClientProvider eventClientProvider)
public XbmcProvider(IConfigService configService, IHttpProvider httpProvider, EventClientProvider eventClientProvider)
{
_configService = configService;
_httpProvider = httpProvider;

@ -12,13 +12,13 @@ namespace NzbDrone.Core.Providers
{
public class XemCommunicationProvider
{
private readonly HttpProvider _httpProvider;
private readonly IHttpProvider _httpProvider;
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
private const string XEM_BASE_URL = "http://thexem.de/map/";
public XemCommunicationProvider(HttpProvider httpProvider)
public XemCommunicationProvider(IHttpProvider httpProvider)
{
_httpProvider = httpProvider;
}

Loading…
Cancel
Save