using System.Globalization; using Microsoft.Extensions.Logging; using Piwigo.Client.Contract; namespace Piwigo.Client; public class ImageApi : IImageApi { private const string DateFormat = "yyyy-MM-dd"; private const string DateTimeFormat = "yyyy-MM-dd HH:mm:ss"; private readonly IPiwigoContext _context; private readonly ILogger _logger; public ImageApi(IPiwigoContext context, ILogger logger) { _context = context ?? throw new ArgumentNullException(nameof(context)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public async Task AddChunkAsync(byte[] data, string originalSum, int position, CancellationToken cancellationToken = default) { var base64Data = Convert.ToBase64String(data); var formParams = new Dictionary { { "data", base64Data }, { "original_sum", originalSum }, // type = file is required for compatibility reasons. // There is no other value allowed { "type", "file" }, { "position", position.ToString() } }; await _context.PostAsync(_logger, "pwg.images.addChunk", formParams, cancellationToken); } public Task AddAsync(ImageUpload imageUpload, CancellationToken cancellationToken = default) { return AddOrUpdateAsync(null, imageUpload, cancellationToken); } public Task UpdateAsync(int imageId, ImageUpload imageUpload, CancellationToken cancellationToken = default) { return AddOrUpdateAsync(imageId, imageUpload, cancellationToken); } public async Task GetInfoAsync(int imageId, int? commentsPage, int? commentsPerPage, CancellationToken cancellationToken = default) { var formParams = new Dictionary { { "image_id", imageId.ToString() } }; formParams.AddIfValueNotNull("comments_page", commentsPage?.ToString()); formParams.AddIfValueNotNull("comments_per_page", commentsPerPage?.ToString()); var response = await _context.PostAsync>(_logger, "pwg.images.getInfo", formParams, cancellationToken); return response.Result; } public async Task ReadyForUploadAsync(CancellationToken cancellationToken = default) { var response = await _context.PostAsync>(_logger, "pwg.images.checkUpload", new Dictionary(), cancellationToken); return response.Result.IsReady; } public async Task GetImages(int albumId, bool recursive, PagingInfo page, ImageFilter filter, ImageOrder order = ImageOrder.Name, CancellationToken cancellationToken = default) { var orderValue = order switch { ImageOrder.Id => "id", ImageOrder.File => "file", ImageOrder.Name => "name", ImageOrder.Hit => "hit", ImageOrder.RatingScore => "rating_score", ImageOrder.DateCreation => "date_creation", ImageOrder.DateAvailable => "date_available", ImageOrder.Random => "random", _ => throw new ArgumentOutOfRangeException(nameof(order), order, null) }; var formParams = new Dictionary { { "cat_id", albumId.ToString() }, { "recursive", recursive.ToString() }, { "per_page", page.PageSize.ToString() }, { "page", page.Page.ToString() }, { "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)); } var response = await _context.PostAsync>(_logger, "pwg.categories.getImages", formParams, cancellationToken); return response.Result; } private async Task AddOrUpdateAsync(int? imageId, ImageUpload imageUpload, CancellationToken cancellationToken) { var formParams = new Dictionary { { "original_sum", imageUpload.OriginalSum }, { "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("image_id", imageId?.ToString()); var response = await _context.PostAsync>(_logger, "pwg.images.add", formParams, cancellationToken); return response.Result; } }