diff --git a/PiwigoDotnet/Piwigo.Client.Tests/ImageApiTests.cs b/PiwigoDotnet/Piwigo.Client.Tests/ImageApiTests.cs index 3dcb51e..6076b5c 100644 --- a/PiwigoDotnet/Piwigo.Client.Tests/ImageApiTests.cs +++ b/PiwigoDotnet/Piwigo.Client.Tests/ImageApiTests.cs @@ -8,6 +8,7 @@ namespace Piwigo.Client.Tests; public class ImageApiTests : ApiTestsBase { private IImageApi _imageApi = null!; + private const string ApiToken = "37ff55f201cf54eadf11f734a74f1d0e"; protected override void OnSetUp() { @@ -15,6 +16,121 @@ public class ImageApiTests : ApiTestsBase _imageApi = new ImageApi(Context, new NullLogger()); } + [Test] + public async Task SetInfoAsync_should_pass_correct_mapped_values_to_piwigo() + { + SetOkResult(); + + var albums = new List<(int AlbumId, int? Rank)> + { + new ValueTuple(3, 10), + new ValueTuple(5, null), + new ValueTuple(7, 11) + }; + var imageInfo = new ImageInfo + { + Author = "unit test", + Comment = "perfect image", + Level = 42, + Name = "Image001.jpg", + CreatedAt = new DateTime(2022, 10, 22, 21, 50, 42), + FileName = "RAW-Image001.jpg", + Albums = albums, + TagIds = new List { 2, 4, 8 } + }; + + await _imageApi.SetInfoAsync(4, imageInfo); + + CorrectMethodShouldGetCalled("pwg.images.setInfo"); + + CorrectParamShouldGetSent("image_id", "4"); + CorrectParamShouldGetSent("file", imageInfo.FileName); + CorrectParamShouldGetSent("name", imageInfo.Name); + CorrectParamShouldGetSent("author", imageInfo.Author); + CorrectParamShouldGetSent("date_creation", "2022-10-22 21:50:42"); + CorrectParamShouldGetSent("comment", imageInfo.Comment); + CorrectParamShouldGetSent("level", imageInfo.Level.ToString()!); + CorrectParamShouldGetSent("categories", "3,10;5;7,11"); + CorrectParamShouldGetSent("tag_ids", "2,4,8"); + CorrectParamShouldGetSent("single_value_mode", "fill_if_empty"); + CorrectParamShouldGetSent("multiple_value_mode", "append"); + } + + [Test] + public async Task RateAsync_should_pass_correct_values_to_server_and_return_correctly_mapped_result() + { + SetJsonResult(@"{""stat"":""ok"",""result"":{""score"":5,""average"":4.5,""count"":""2""}}"); + + var rating = await _imageApi.RateAsync(4, 5); + + rating.Score.Should().Be(5); + rating.Average.Should().Be(4.5f); + rating.Count.Should().Be(2); + + CorrectMethodShouldGetCalled("pwg.images.rate"); + CorrectParamShouldGetSent("image_id", "4"); + CorrectParamShouldGetSent("rate", "5"); + } + + [Test] + public async Task ExistsByMd5SumsAsync_should_pass_correct_values_to_server_and_return_correctly_mapped_result() + { + SetJsonResult(@"{""stat"":""ok"",""result"":{""2c6d9eab0c567d5f96c53825ae53f3d4"":""4"",""ee45c441b8ea4bcb3ab9b7a51370b242"":null}}"); + + var existsResult = await _imageApi.ExistsByMd5SumsAsync(new[] { "2c6d9eab0c567d5f96c53825ae53f3d4", "ee45c441b8ea4bcb3ab9b7a51370b242" }); + + existsResult.Should().HaveCount(2); + existsResult["2c6d9eab0c567d5f96c53825ae53f3d4"].Should().Be(4); + existsResult["ee45c441b8ea4bcb3ab9b7a51370b242"].Should().BeNull(); + + CorrectMethodShouldGetCalled("pwg.images.exist"); + CorrectParamShouldGetSent("md5sum_list", "2c6d9eab0c567d5f96c53825ae53f3d4,ee45c441b8ea4bcb3ab9b7a51370b242"); + } + + [Test] + public async Task DeleteOrphansAsync_should_pass_request_toPiwigo_and_return_performed_results() + { + SetJsonResult(@"{""stat"":""ok"",""result"":{""nb_deleted"":10,""nb_orphans"":154}}"); + + var (deleted, orphans) = await _imageApi.DeleteOrphansAsync(ApiToken, 10); + + deleted.Should().Be(10); + orphans.Should().Be(154); + + CorrectMethodShouldGetCalled("pwg.images.deleteOrphans"); + CorrectParamShouldGetSent("block_size", "10"); + CorrectParamShouldGetSent("pwg_token", ApiToken); + } + + [Test] + public async Task DeleteAsync_should_pass_request_toPiwigo_and_return_success() + { + SetJsonResult(@"{""stat"":""ok"",""result"":1}"); + + var result = await _imageApi.DeleteAsync(1, ApiToken); + + result.Should().Be(true); + + CorrectMethodShouldGetCalled("pwg.images.delete"); + CorrectParamShouldGetSent("image_id", "1"); + CorrectParamShouldGetSent("pwg_token", ApiToken); + } + + [Test] + public async Task CheckImageAsync_should_pass_data_to_piwigo_and_return_status() + { + SetJsonResult(@"{""stat"":""ok"",""result"":{""file"":""differs""}}"); + + const string md5Sum = "ee45c441b8ea4bcb3ab9b7a51370b242"; + var result = await _imageApi.CheckImageAsync(1, md5Sum); + + result.Should().Be(ImageCheckStatus.Differs); + + CorrectMethodShouldGetCalled("pwg.images.checkFiles"); + CorrectParamShouldGetSent("image_id", "1"); + CorrectParamShouldGetSent("file_sum", md5Sum); + } + [Test] public async Task AddComment_should_pass_data_to_piwigo_and_return_new_comment() { @@ -64,7 +180,7 @@ public class ImageApiTests : ApiTestsBase CorrectMethodShouldGetCalled("pwg.images.add"); - CorrectParamShouldGetSent("original_filename", imageUpload.OriginalFileName!); + CorrectParamShouldGetSent("original_filename", imageUpload.FileName!); CorrectParamShouldGetSent("name", imageUpload.Name!); CorrectParamShouldGetSent("author", imageUpload.Author!); CorrectParamShouldGetSent("date_creation", "2022-10-22 21:50:42"); @@ -97,7 +213,7 @@ public class ImageApiTests : ApiTestsBase // Piwigo uses the same request for add or update depending on this parameter ParamShouldNotGetSent("image_id"); - CorrectParamShouldGetSent("original_filename", imageUpload.OriginalFileName!); + CorrectParamShouldGetSent("original_filename", imageUpload.FileName!); CorrectParamShouldGetSent("name", imageUpload.Name!); CorrectParamShouldGetSent("author", imageUpload.Author!); CorrectParamShouldGetSent("date_creation", "2022-10-22 21:50:42"); @@ -146,7 +262,7 @@ public class ImageApiTests : ApiTestsBase { await SetJsonResultFromFileAsync("ImageApi.getImages.json"); - var result = await _imageApi.GetImages(7, true, new PagingInfo(0, 100, 0), ImageFilter.Empty); + var result = await _imageApi.GetImagesAsync(7, true, new ImagePagingInfo(0, 100, 0), ImageFilter.Empty); CorrectMethodShouldGetCalled("pwg.categories.getImages"); CorrectParamShouldGetSent("cat_id", "7"); @@ -173,7 +289,7 @@ public class ImageApiTests : ApiTestsBase Level = 42, Name = "Image001.jpg", CreatedAt = new DateTime(2022, 10, 22, 21, 50, 42), - OriginalFileName = "RAW-Image001.jpg", + FileName = "RAW-Image001.jpg", Albums = albums, TagIds = new List { 2, 4, 8 } }; diff --git a/PiwigoDotnet/Piwigo.Client/Contract/CheckFilesResult.cs b/PiwigoDotnet/Piwigo.Client/Contract/CheckFilesResult.cs new file mode 100644 index 0000000..e198edf --- /dev/null +++ b/PiwigoDotnet/Piwigo.Client/Contract/CheckFilesResult.cs @@ -0,0 +1,20 @@ +using Newtonsoft.Json; + +namespace Piwigo.Client.Contract; + +public record CheckFilesResult +{ + [JsonProperty("file")] + public string? File { get; init; } + + public ImageCheckStatus ToImageCheckStatus() + { + return File?.ToLower() switch + { + "equals" => ImageCheckStatus.Equals, + "differs" => ImageCheckStatus.Differs, + "missing" => ImageCheckStatus.Missing, + _ => throw new PiwigoException($"Could not convert {File} to {nameof(ImageCheckStatus)} as the returned value is not supported") + }; + } +} \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/Contract/ImageCheckStatus.cs b/PiwigoDotnet/Piwigo.Client/Contract/ImageCheckStatus.cs new file mode 100644 index 0000000..036d949 --- /dev/null +++ b/PiwigoDotnet/Piwigo.Client/Contract/ImageCheckStatus.cs @@ -0,0 +1,8 @@ +namespace Piwigo.Client.Contract; + +public enum ImageCheckStatus +{ + Equals = 0, + Differs, + Missing +} \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/Contract/ImageInfo.cs b/PiwigoDotnet/Piwigo.Client/Contract/ImageInfo.cs new file mode 100644 index 0000000..b00c530 --- /dev/null +++ b/PiwigoDotnet/Piwigo.Client/Contract/ImageInfo.cs @@ -0,0 +1,13 @@ +namespace Piwigo.Client.Contract; + +public record ImageInfo +{ + public string? FileName { get; init; } + public string? Name { get; init; } + public string? Author { get; init; } + public DateTime? CreatedAt { get; init; } + public string? Comment { get; init; } + public int? Level { get; init; } + public IReadOnlyCollection<(int AlbumId, int? Rank)>? Albums { get; init; } + public IReadOnlyCollection? TagIds { get; init; } +} \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/Contract/ImagePagingInfo.cs b/PiwigoDotnet/Piwigo.Client/Contract/ImagePagingInfo.cs new file mode 100644 index 0000000..4d6b4ba --- /dev/null +++ b/PiwigoDotnet/Piwigo.Client/Contract/ImagePagingInfo.cs @@ -0,0 +1,5 @@ +using Newtonsoft.Json; + +namespace Piwigo.Client.Contract; + +public record ImagePagingInfo([property: JsonProperty("page")] int Page, [property: JsonProperty("per_page")] int PageSize, [property: JsonProperty("count")] int TotalItems); \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/Contract/ImageRating.cs b/PiwigoDotnet/Piwigo.Client/Contract/ImageRating.cs new file mode 100644 index 0000000..808c9c0 --- /dev/null +++ b/PiwigoDotnet/Piwigo.Client/Contract/ImageRating.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json; + +namespace Piwigo.Client.Contract; + +public record ImageRating +{ + [JsonProperty("score")] + public int Score { get; set; } + + [JsonProperty("average")] + public float Average { get; set; } + + [JsonProperty("count")] + public int Count { get; set; } +} \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/Contract/ImageUpload.cs b/PiwigoDotnet/Piwigo.Client/Contract/ImageUpload.cs index 7e50a95..eee80fc 100644 --- a/PiwigoDotnet/Piwigo.Client/Contract/ImageUpload.cs +++ b/PiwigoDotnet/Piwigo.Client/Contract/ImageUpload.cs @@ -1,13 +1,3 @@ namespace Piwigo.Client.Contract; -public record ImageUpload(string OriginalSum) -{ - public string? OriginalFileName { get; init; } - public string? Name { get; init; } - public string? Author { get; init; } - public DateTime? CreatedAt { get; init; } - public string? Comment { get; init; } - public int? Level { get; init; } - public IReadOnlyCollection<(int AlbumId, int? Rank)>? Albums { get; init; } - public IReadOnlyCollection? TagIds { get; init; } -} \ No newline at end of file +public record ImageUpload(string OriginalSum) : ImageInfo; \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/Contract/OrphanImagesDeleted.cs b/PiwigoDotnet/Piwigo.Client/Contract/OrphanImagesDeleted.cs new file mode 100644 index 0000000..c999101 --- /dev/null +++ b/PiwigoDotnet/Piwigo.Client/Contract/OrphanImagesDeleted.cs @@ -0,0 +1,18 @@ +using Newtonsoft.Json; + +namespace Piwigo.Client.Contract; + +public record OrphanImagesDeleted +{ + [JsonProperty("nb_deleted")] + public int? Deleted { get; init; } + + [JsonProperty("nb_orphans")] + public int? Orphans { get; init; } + + public void Deconstruct(out int? deleted, out int? orphans) + { + deleted = Deleted; + orphans = Orphans; + } +} \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/Contract/PagedImages.cs b/PiwigoDotnet/Piwigo.Client/Contract/PagedImages.cs index 7aa4998..683dfa4 100644 --- a/PiwigoDotnet/Piwigo.Client/Contract/PagedImages.cs +++ b/PiwigoDotnet/Piwigo.Client/Contract/PagedImages.cs @@ -8,14 +8,14 @@ public class PagedImages { } - public PagedImages(PagingInfo paging, IReadOnlyCollection images) + public PagedImages(ImagePagingInfo paging, IReadOnlyCollection images) { Paging = paging ?? throw new ArgumentNullException(nameof(paging)); Images = images ?? throw new ArgumentNullException(nameof(images)); } [JsonProperty("paging")] - public PagingInfo Paging { get; init; } = null!; + public ImagePagingInfo Paging { get; init; } = null!; [JsonProperty("images")] public IReadOnlyCollection Images { get; init; } = null!; diff --git a/PiwigoDotnet/Piwigo.Client/Contract/PagingInfo.cs b/PiwigoDotnet/Piwigo.Client/Contract/PagingInfo.cs deleted file mode 100644 index 731c645..0000000 --- a/PiwigoDotnet/Piwigo.Client/Contract/PagingInfo.cs +++ /dev/null @@ -1,5 +0,0 @@ -using Newtonsoft.Json; - -namespace Piwigo.Client.Contract; - -public record PagingInfo([property: JsonProperty("page")] int Page, [property: JsonProperty("per_page")] int PageSize, [property: JsonProperty("count")] int TotalItems); \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/Contract/SessionStatus.cs b/PiwigoDotnet/Piwigo.Client/Contract/SessionStatus.cs index 0ccdaef..37eff20 100644 --- a/PiwigoDotnet/Piwigo.Client/Contract/SessionStatus.cs +++ b/PiwigoDotnet/Piwigo.Client/Contract/SessionStatus.cs @@ -2,7 +2,7 @@ using Newtonsoft.Json; namespace Piwigo.Client.Contract; -public class SessionStatus +public record SessionStatus { [JsonProperty("username")] public string? Username { get; init; } @@ -17,7 +17,7 @@ public class SessionStatus public string? Language { get; init; } [JsonProperty("pwg_token")] - public string? PwgToken { get; init; } + public string? ApiToken { get; init; } [JsonProperty("charset")] public string? Charset { get; init; } diff --git a/PiwigoDotnet/Piwigo.Client/Contract/ValueUpdateMode.cs b/PiwigoDotnet/Piwigo.Client/Contract/ValueUpdateMode.cs new file mode 100644 index 0000000..6f8264a --- /dev/null +++ b/PiwigoDotnet/Piwigo.Client/Contract/ValueUpdateMode.cs @@ -0,0 +1,15 @@ +namespace Piwigo.Client.Contract; + +public enum ValueUpdateMode +{ + /// + /// Appends the values to the current one if it is a list or + /// just set the value if it is not present in single mode + /// + Append = 0, + + /// + /// Replaces the values with the provided ones + /// + Replace +} \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/IGroupApi.cs b/PiwigoDotnet/Piwigo.Client/IGroupApi.cs deleted file mode 100644 index fadd426..0000000 --- a/PiwigoDotnet/Piwigo.Client/IGroupApi.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Piwigo.Client; - -public interface IGroupApi {} \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/IImageApi.cs b/PiwigoDotnet/Piwigo.Client/IImageApi.cs index c528203..ec7dab6 100644 --- a/PiwigoDotnet/Piwigo.Client/IImageApi.cs +++ b/PiwigoDotnet/Piwigo.Client/IImageApi.cs @@ -87,27 +87,82 @@ public interface IImageApi /// /// /// a paged list of the images of a given album - Task GetImages(int albumId, bool recursive, PagingInfo page, ImageFilter filter, ImageOrder order = ImageOrder.Name, + Task GetImagesAsync(int albumId, bool recursive, ImagePagingInfo page, ImageFilter filter, ImageOrder order = ImageOrder.Name, CancellationToken cancellationToken = default); - /* -checkFiles -delete -deleteOrphans -emptyLounge -exist --> formats - delete - searchImage -rate -search -setInfo -setMd5sum -setPrivacyLevel -setRank -syncMetadata -upload -uploadAsync -uploadCompleted -*/ + /// + /// Checks if an image is the same as on the server. + /// + /// The image id + /// The md5 checksum of the given image + /// + /// + /// + /// + /// + /// + Task CheckImageAsync(int imageId, string md5Sum, CancellationToken cancellationToken = default); + + /// + /// Deletes the given image from the server. + /// + /// the image id to delete + /// The API token that can be read from + /// + /// + /// + /// true if the image was found and removed; false if it does not exist + Task DeleteAsync(int imageId, string apiToken, CancellationToken cancellationToken = default); + + /// + /// Deletes a block of orphaned images from the server and returns the number of remaining orphans. + /// + /// The API token that can be read from + /// Number of orphaned images to delete in this call + /// + /// + /// + /// The number of deleted orphans and the number of remaining orphan images. + Task DeleteOrphansAsync(string apiToken, int? blockSize = null, CancellationToken cancellationToken = default); + + /// + /// Checks if the given images can be found by their md5 sum. + /// This method will only return any information if the configuration of your server contains the following setting: + /// $conf[uniqueness_mode]==md5sum + /// + /// A enumerable of md5sums to check against the piwigo instance + /// + /// + /// + /// + /// A dictionary containing the md5sum as key and the image id as value. The image id is null if the image does + /// not exist. + /// + Task> ExistsByMd5SumsAsync(IEnumerable md5Sums, CancellationToken cancellationToken = default); + + /// + /// Rates an image. This function only works if you have image rating enabled on your instance under Admin -> + /// Configuration -> Options -> General in section Permission. + /// + /// The image id that should get this rate + /// Rating from 0 to 5 + /// + /// + /// + /// Your current rating and the average score including number of rates. + Task RateAsync(int imageId, int rate, CancellationToken cancellationToken = default); + + /// + /// Updates or replaces image information depending on the provided update modes. + /// + /// Image id to update + /// The image information to use + /// UpdateMode for single value fields: + /// UpdateMode for multi value fields: + /// + /// + /// + /// + Task SetInfoAsync(int imageId, ImageInfo imageInfo, ValueUpdateMode singleValueMode = ValueUpdateMode.Append, ValueUpdateMode multiValueMode = ValueUpdateMode.Append, + CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/IPermissionApi.cs b/PiwigoDotnet/Piwigo.Client/IPermissionApi.cs deleted file mode 100644 index acc3ae8..0000000 --- a/PiwigoDotnet/Piwigo.Client/IPermissionApi.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Piwigo.Client; - -public interface IPermissionApi {} \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/IPiwigoClient.cs b/PiwigoDotnet/Piwigo.Client/IPiwigoClient.cs index 83ef54e..b67a7b6 100644 --- a/PiwigoDotnet/Piwigo.Client/IPiwigoClient.cs +++ b/PiwigoDotnet/Piwigo.Client/IPiwigoClient.cs @@ -2,11 +2,8 @@ public interface IPiwigoClient { - IGroupApi Group { get; } IImageApi Image { get; } - IPermissionApi Permission { get; } ITagApi Tag { get; } - IUserApi User { get; } ISessionApi Session { get; } IAlbumApi Album { get; } } \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/IUserApi.cs b/PiwigoDotnet/Piwigo.Client/IUserApi.cs deleted file mode 100644 index f7cf15e..0000000 --- a/PiwigoDotnet/Piwigo.Client/IUserApi.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Piwigo.Client; - -public interface IUserApi {} \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/ImageApi.cs b/PiwigoDotnet/Piwigo.Client/ImageApi.cs index 900b1cc..bcf12da 100644 --- a/PiwigoDotnet/Piwigo.Client/ImageApi.cs +++ b/PiwigoDotnet/Piwigo.Client/ImageApi.cs @@ -27,7 +27,7 @@ public class ImageApi : IImageApi { "key", key } }; formParams.AddIfValueNotNull("author", author); - + var response = await _context.PostAsync>(_logger, "pwg.images.addComment", formParams, cancellationToken); return response.Result.Comment.Id; @@ -78,7 +78,102 @@ public class ImageApi : IImageApi return response.Result.IsReady; } - public async Task GetImages(int albumId, bool recursive, PagingInfo page, ImageFilter filter, ImageOrder order = ImageOrder.Name, + public async Task CheckImageAsync(int imageId, string md5Sum, CancellationToken cancellationToken = default) + { + var formParams = new Dictionary + { + { "image_id", imageId.ToString() }, + { "file_sum", md5Sum } + }; + + var response = await _context.PostAsync>(_logger, "pwg.images.checkFiles", formParams, cancellationToken); + + return response.Result.ToImageCheckStatus(); + } + + public async Task DeleteAsync(int imageId, string apiToken, CancellationToken cancellationToken = default) + { + var formParams = new Dictionary + { + { "image_id", imageId.ToString() }, + { "pwg_token", apiToken } + }; + + var response = await _context.PostAsync>(_logger, "pwg.images.delete", formParams, cancellationToken); + + return response.Result; + } + + public async Task DeleteOrphansAsync(string apiToken, int? blockSize = null, CancellationToken cancellationToken = default) + { + var formParams = new Dictionary + { + { "pwg_token", apiToken } + }; + formParams.AddIfValueNotNull("block_size", blockSize?.ToString()); + + var response = await _context.PostAsync>(_logger, "pwg.images.deleteOrphans", formParams, cancellationToken); + + return response.Result; + } + + public async Task> ExistsByMd5SumsAsync(IEnumerable md5Sums, CancellationToken cancellationToken = default) + { + var formParams = new Dictionary + { + { "md5sum_list", string.Join(",", md5Sums) } + }; + + var response = await _context.PostAsync>>(_logger, "pwg.images.exist", formParams, cancellationToken); + + return response.Result; + } + + public async Task RateAsync(int imageId, int rate, CancellationToken cancellationToken = default) + { + var formParams = new Dictionary + { + { "image_id", imageId.ToString() }, + { "rate", rate.ToString() } + }; + + var response = await _context.PostAsync>(_logger, "pwg.images.rate", formParams, cancellationToken); + + return response.Result; + } + + public async Task SetInfoAsync(int imageId, ImageInfo imageInfo, ValueUpdateMode singleValueMode = ValueUpdateMode.Append, + ValueUpdateMode multiValueMode = ValueUpdateMode.Append, + CancellationToken cancellationToken = default) + { + var singleMode = singleValueMode switch + { + ValueUpdateMode.Append => "fill_if_empty", + ValueUpdateMode.Replace => "replace", + _ => throw new ArgumentOutOfRangeException(nameof(singleValueMode), singleValueMode, null) + }; + + var multiMode = multiValueMode switch + { + ValueUpdateMode.Append => "append", + ValueUpdateMode.Replace => "replace", + _ => throw new ArgumentOutOfRangeException(nameof(singleValueMode), singleValueMode, null) + }; + + var formParams = new Dictionary + { + { "image_id", imageId.ToString() }, + { "single_value_mode", singleMode }, + { "multiple_value_mode", multiMode } + }; + + formParams.AddIfValueNotNull("file", imageInfo.FileName); + AddImageInfoToForm(formParams, imageInfo); + + await _context.PostAsync(_logger, "pwg.images.setInfo", formParams, cancellationToken); + } + + public async Task GetImagesAsync(int albumId, bool recursive, ImagePagingInfo page, ImageFilter filter, ImageOrder order = ImageOrder.Name, CancellationToken cancellationToken = default) { var orderValue = order switch @@ -103,60 +198,17 @@ public class ImageApi : IImageApi { "order", orderValue } }; - if (filter.MinRate.HasValue) - { - formParams.Add("f_min_rate", filter.MinRate.Value.ToString(CultureInfo.InvariantCulture)); - } - - if (filter.MaxRate.HasValue) - { - formParams.Add("f_max_rate", filter.MaxRate.Value.ToString(CultureInfo.InvariantCulture)); - } - - if (filter.MinHit.HasValue) - { - formParams.Add("f_min_hit", filter.MinHit.Value.ToString()); - } - - if (filter.MaxHit.HasValue) - { - formParams.Add("f_max_hit", filter.MaxHit.Value.ToString()); - } - - if (filter.MinRatio.HasValue) - { - formParams.Add("f_min_ratio", filter.MinRatio.Value.ToString(CultureInfo.InvariantCulture)); - } - - if (filter.MaxRatio.HasValue) - { - formParams.Add("f_max_ratio", filter.MaxRatio.Value.ToString(CultureInfo.InvariantCulture)); - } - - if (filter.MaxLevel.HasValue) - { - formParams.Add("f_max_level", filter.MaxLevel.Value.ToString()); - } - - if (filter.MinDateAvailable.HasValue) - { - formParams.Add("f_min_date_available", filter.MinDateAvailable.Value.ToString(DateFormat)); - } - - if (filter.MaxDataAvailable.HasValue) - { - formParams.Add("f_max_date_available", filter.MaxDataAvailable.Value.ToString(DateFormat)); - } - - if (filter.MinDateCreated.HasValue) - { - formParams.Add("f_min_date_created", filter.MinDateCreated.Value.ToString(DateFormat)); - } - - if (filter.MaxDateCreated.HasValue) - { - formParams.Add("f_max_date_created", filter.MaxDateCreated.Value.ToString(DateFormat)); - } + formParams.AddIfValueNotNull("f_min_rate", filter.MinRate?.ToString(CultureInfo.InvariantCulture)); + formParams.AddIfValueNotNull("f_max_rate", filter.MaxRate?.ToString(CultureInfo.InvariantCulture)); + formParams.AddIfValueNotNull("f_min_hit", filter.MinHit?.ToString()); + formParams.AddIfValueNotNull("f_max_hit", filter.MaxHit?.ToString()); + formParams.AddIfValueNotNull("f_min_ratio", filter.MinRatio?.ToString(CultureInfo.InvariantCulture)); + formParams.AddIfValueNotNull("f_max_ratio", filter.MaxRatio?.ToString(CultureInfo.InvariantCulture)); + formParams.AddIfValueNotNull("f_max_level", filter.MaxLevel?.ToString()); + formParams.AddIfValueNotNull("f_min_date_available", filter.MinDateAvailable?.ToString(DateFormat)); + formParams.AddIfValueNotNull("f_max_date_available", filter.MaxDataAvailable?.ToString(DateFormat)); + formParams.AddIfValueNotNull("f_min_date_created", filter.MinDateCreated?.ToString(DateFormat)); + formParams.AddIfValueNotNull("f_max_date_created", filter.MaxDateCreated?.ToString(DateFormat)); var response = await _context.PostAsync>(_logger, "pwg.categories.getImages", formParams, cancellationToken); return response.Result; @@ -170,22 +222,27 @@ public class ImageApi : IImageApi { "check_uniqueness", "true" } }; - formParams.AddIfValueNotNull("original_filename", imageUpload.OriginalFileName); - formParams.AddIfValueNotNull("name", imageUpload.Name); - formParams.AddIfValueNotNull("author", imageUpload.Author); - formParams.AddIfValueNotNull("date_creation", imageUpload.CreatedAt?.ToString(DateTimeFormat)); - formParams.AddIfValueNotNull("comment", imageUpload.Comment); - formParams.AddIfValueNotNull("level", imageUpload.Level?.ToString()); - - var albums = imageUpload.Albums != null ? string.Join(";", imageUpload.Albums.Select(a => a.Rank.HasValue ? $"{a.AlbumId},{a.Rank}" : $"{a.AlbumId}")) : null; - formParams.AddIfValueNotNull("categories", albums); - - var tags = imageUpload.TagIds != null ? string.Join(",", imageUpload.TagIds.Select(t => t.ToString())) : null; - formParams.AddIfValueNotNull("tag_ids", tags); + formParams.AddIfValueNotNull("original_filename", imageUpload.FileName); + AddImageInfoToForm(formParams, imageUpload); formParams.AddIfValueNotNull("image_id", imageId?.ToString()); var response = await _context.PostAsync>(_logger, "pwg.images.add", formParams, cancellationToken); return response.Result; } + + private static void AddImageInfoToForm(IDictionary formParams, ImageInfo imageInfo) + { + formParams.AddIfValueNotNull("name", imageInfo.Name); + formParams.AddIfValueNotNull("author", imageInfo.Author); + formParams.AddIfValueNotNull("date_creation", imageInfo.CreatedAt?.ToString(DateTimeFormat)); + formParams.AddIfValueNotNull("comment", imageInfo.Comment); + formParams.AddIfValueNotNull("level", imageInfo.Level?.ToString()); + + var albums = imageInfo.Albums != null ? string.Join(";", imageInfo.Albums.Select(a => a.Rank.HasValue ? $"{a.AlbumId},{a.Rank}" : $"{a.AlbumId}")) : null; + formParams.AddIfValueNotNull("categories", albums); + + var tags = imageInfo.TagIds != null ? string.Join(",", imageInfo.TagIds.Select(t => t.ToString())) : null; + formParams.AddIfValueNotNull("tag_ids", tags); + } } \ No newline at end of file diff --git a/PiwigoDotnet/Piwigo.Client/PiwigoClient.cs b/PiwigoDotnet/Piwigo.Client/PiwigoClient.cs index aba1d3f..13a2808 100644 --- a/PiwigoDotnet/Piwigo.Client/PiwigoClient.cs +++ b/PiwigoDotnet/Piwigo.Client/PiwigoClient.cs @@ -2,22 +2,16 @@ namespace Piwigo.Client; public class PiwigoClient : IPiwigoClient { - public PiwigoClient(IGroupApi group, IImageApi image, IPermissionApi permission, ITagApi tag, IUserApi user, ISessionApi session, IAlbumApi album) + public PiwigoClient(IImageApi image, ITagApi tag, ISessionApi session, IAlbumApi album) { - Group = group ?? throw new ArgumentNullException(nameof(group)); Image = image ?? throw new ArgumentNullException(nameof(image)); - Permission = permission ?? throw new ArgumentNullException(nameof(permission)); Tag = tag ?? throw new ArgumentNullException(nameof(tag)); - User = user ?? throw new ArgumentNullException(nameof(user)); Session = session ?? throw new ArgumentNullException(nameof(session)); Album = album ?? throw new ArgumentNullException(nameof(album)); } - public IGroupApi Group { get; } public IImageApi Image { get; } - public IPermissionApi Permission { get; } public ITagApi Tag { get; } - public IUserApi User { get; } public ISessionApi Session { get; } public IAlbumApi Album { get; } } \ No newline at end of file