diff --git a/PiwigoDotnet/Piwigo.Client.Tests/PiwigoClientTests.cs b/PiwigoDotnet/Piwigo.Client.Tests/PiwigoClientTests.cs index a507507..50defcc 100644 --- a/PiwigoDotnet/Piwigo.Client.Tests/PiwigoClientTests.cs +++ b/PiwigoDotnet/Piwigo.Client.Tests/PiwigoClientTests.cs @@ -1,23 +1,30 @@ +using System.Text.Json; using Flurl.Http.Testing; +using Microsoft.Extensions.Logging.Abstractions; namespace Piwigo.Client.Tests; +[TestFixture] public class PiwigoClientTests { + private const string TestUri = "http://localhost:8080/ws.php?format=json"; + private const string Username = "admin"; + private const string Password = "admin"; + private PiwigoClient _piwigoClient = null!; - private HttpTest _httpTest = null!; + private HttpTest? _httpTest; [SetUp] public void SetUp() { - _piwigoClient = new PiwigoClient(); + _piwigoClient = new PiwigoClient(new NullLogger()); _httpTest = new HttpTest(); } [TearDown] public void TearDown() { - _httpTest.Dispose(); + _httpTest?.Dispose(); } [Test] @@ -26,20 +33,45 @@ public class PiwigoClientTests await LoginAsync(); } + [Test] + public async Task GetStatus_should_return_config() + { + await LoginAsync(); + + var expectedResponse = new PiwigoResponse + { + Status = "OK", + Result = new PiwigoStatus + { + Username = "admin", + Version = "12.0.0" + } + }; + var jsonResponse = JsonSerializer.Serialize(expectedResponse); + _httpTest?.RespondWith(jsonResponse); + + var status = await _piwigoClient.GetStatusAsync(); + + status.Should().NotBeNull(); + status.Username.Should().Be("admin"); + status.Version.Should().NotBeEmpty(); + } + [Test] public async Task Logout_should_set_IsLoggedIn_to_false() { await LoginAsync(); - _httpTest.RespondWith("OK"); - await _piwigoClient.Logout(); + _httpTest?.RespondWith("OK"); + await _piwigoClient.LogoutAsync(); _piwigoClient.IsLoggedIn.Should().BeFalse(); } + private async Task LoginAsync() { - _httpTest.RespondWith("OK", 200, cookies: new { pwg_id = "pwg_id" }); - await _piwigoClient.LoginAsync(new Uri("http://localhost:8080/foo/bar/ws.php?format=json"), "admin", "admin"); + _httpTest?.RespondWith("{}", 200, cookies: new { pwg_id = "pwg_id" }); + await _piwigoClient.LoginAsync(new Uri(TestUri), Username, Password); _piwigoClient.IsLoggedIn.Should().BeTrue(); } } \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client.Tests/appsettings.json b/PiwigoDotnet/Piwigo.Client.Tests/appsettings.json new file mode 100644 index 0000000..34204c5 --- /dev/null +++ b/PiwigoDotnet/Piwigo.Client.Tests/appsettings.json @@ -0,0 +1,14 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "System": "Warning", + "Microsoft": "Warning" + }, + "Debug": { + "LogLevel": { + "Default": "Debug" + } + } + } +} \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/Assemblyinfo.cs b/PiwigoDotnet/Piwigo.Client/Assemblyinfo.cs new file mode 100644 index 0000000..0d44aba --- /dev/null +++ b/PiwigoDotnet/Piwigo.Client/Assemblyinfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Piwigo.Client.Tests")] \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/IPiwigoClient.cs b/PiwigoDotnet/Piwigo.Client/IPiwigoClient.cs index 94aa902..58a0301 100644 --- a/PiwigoDotnet/Piwigo.Client/IPiwigoClient.cs +++ b/PiwigoDotnet/Piwigo.Client/IPiwigoClient.cs @@ -5,5 +5,6 @@ public interface IPiwigoClient bool IsLoggedIn { get; } int ChunkSize { get; set; } Task LoginAsync(Uri uri, string username, string password); - Task Logout(); + Task LogoutAsync(); + Task GetStatusAsync(); } \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/Piwigo.Client.csproj b/PiwigoDotnet/Piwigo.Client/Piwigo.Client.csproj index f4544b6..cecd204 100644 --- a/PiwigoDotnet/Piwigo.Client/Piwigo.Client.csproj +++ b/PiwigoDotnet/Piwigo.Client/Piwigo.Client.csproj @@ -5,7 +5,7 @@ enable enable - + diff --git a/PiwigoDotnet/Piwigo.Client/PiwigoClient.cs b/PiwigoDotnet/Piwigo.Client/PiwigoClient.cs index be8d2dc..e8db4c3 100644 --- a/PiwigoDotnet/Piwigo.Client/PiwigoClient.cs +++ b/PiwigoDotnet/Piwigo.Client/PiwigoClient.cs @@ -1,7 +1,9 @@ +using System.Diagnostics; using System.Net; using System.Runtime.CompilerServices; using Flurl; using Flurl.Http; +using Microsoft.Extensions.Logging; namespace Piwigo.Client; @@ -11,7 +13,14 @@ public class PiwigoClient : IPiwigoClient private string _piwigoBaseUri = null!; public bool IsLoggedIn { get; private set; } public int ChunkSize { get; set; } = 512; - private IFlurlRequest Request => _piwigoBaseUri.WithCookies(_cookies); + private IFlurlRequest Request => _piwigoBaseUri.WithCookies(_cookies).ConfigureRequest(r => r.AfterCallAsync = LogResponse); + + private readonly ILogger _logger; + + public PiwigoClient(ILogger logger) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } public async Task LoginAsync(Uri uri, string username, string password) { @@ -37,28 +46,43 @@ public class PiwigoClient : IPiwigoClient _piwigoBaseUri = uri.AppendPathSegment("ws.php").SetQueryParam("format", "json"); + _logger.LogInformation("Logging into {PiwigoBaseUri} using username {Username}", _piwigoBaseUri, username); + var response = await _piwigoBaseUri.WithCookies(out var cookieJar).PostMultipartAsync(c => c.PiwigoLogin(username, password)); if (response.StatusCode != (int)HttpStatusCode.OK) { + _logger.LogError("Failed to log in {StatusCode}", response.StatusCode); throw new PiwigoException($"Could not log in to {_piwigoBaseUri} using username {username}"); } + _logger.LogInformation("Logging in succeeded"); _cookies = cookieJar; IsLoggedIn = true; } - public async Task Logout() + public async Task LogoutAsync() { EnsureLoggedIn(); + _logger.LogInformation("Logging out from {Uri}", _piwigoBaseUri); await Request.PostMultipartAsync(c => c.PiwigoLogout()); IsLoggedIn = false; _cookies.Clear(); } + public async Task GetStatusAsync() + { + EnsureLoggedIn(); + + _logger.LogInformation("Getting status"); + var response = await Request.PostMultipartAsync(c => c.PiwigoGetStatus()); + var typedResponse = await response.GetJsonAsync>(); + return typedResponse.Result; + } + private void EnsureLoggedIn([CallerMemberName] string? callerName = null) { if (!IsLoggedIn) @@ -66,4 +90,10 @@ public class PiwigoClient : IPiwigoClient throw new InvalidOperationException($"Could not execute {callerName} as the client is not logged in."); } } + + private async Task LogResponse(FlurlCall call) + { + var responseString = await call.Response.GetStringAsync(); + _logger.LogDebug("PiwigoResponse: {Response}", responseString); + } } \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/PiwigoMethods.cs b/PiwigoDotnet/Piwigo.Client/PiwigoMethods.cs index 5146e29..0ec2717 100644 --- a/PiwigoDotnet/Piwigo.Client/PiwigoMethods.cs +++ b/PiwigoDotnet/Piwigo.Client/PiwigoMethods.cs @@ -14,4 +14,9 @@ internal static class PiwigoMethods { return part.AddMethod("pwg.session.logout"); } + + public static CapturedMultipartContent PiwigoGetStatus(this CapturedMultipartContent part) + { + return part.AddMethod("pwg.session.getStatus"); + } } \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/PiwigoResponse.cs b/PiwigoDotnet/Piwigo.Client/PiwigoResponse.cs new file mode 100644 index 0000000..bdb01dc --- /dev/null +++ b/PiwigoDotnet/Piwigo.Client/PiwigoResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Piwigo.Client; + +internal class PiwigoResponse +{ + [JsonProperty("stat")] + public string? Status { get; init; } + + [JsonProperty("result")] + public T Result { get; init; } = default!; +} \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/PiwigoStatus.cs b/PiwigoDotnet/Piwigo.Client/PiwigoStatus.cs new file mode 100644 index 0000000..9589fbe --- /dev/null +++ b/PiwigoDotnet/Piwigo.Client/PiwigoStatus.cs @@ -0,0 +1,39 @@ +using Newtonsoft.Json; + +namespace Piwigo.Client; + +public class PiwigoStatus +{ + [JsonProperty("username")] + public string? Username { get; init; } + + [JsonProperty("status")] + public string? Status { get; init; } + + [JsonProperty("theme")] + public string? Theme { get; init; } + + [JsonProperty("language")] + public string? Language { get; init; } + + [JsonProperty("pwg_token")] + public string? PwgToken { get; init; } + + [JsonProperty("charset")] + public string? Charset { get; init; } + + [JsonProperty("current_datetime")] + public string? CurrentDatetime { get; init; } + + [JsonProperty("version")] + public string? Version { get; init; } + + [JsonProperty("available_sizes")] + public string[]? AvailableSizes { get; init; } + + [JsonProperty("upload_file_types")] + public string? UploadFileTypes { get; init; } + + [JsonProperty("upload_form_chunk_size")] + public int UploadFormChunkSize { get; init; } = 512; +} \ No newline at end of file diff --git a/PiwigoDotnet/PiwigoDotnet.sln.DotSettings b/PiwigoDotnet/PiwigoDotnet.sln.DotSettings index 7a6b9ad..82ba786 100644 --- a/PiwigoDotnet/PiwigoDotnet.sln.DotSettings +++ b/PiwigoDotnet/PiwigoDotnet.sln.DotSettings @@ -3,4 +3,7 @@ Required Required Required + NEVER + NEVER + 180 True \ No newline at end of file