2022-10-21 00:23:54 +02:00
|
|
|
using System.Globalization;
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
using Piwigo.Client.Contract;
|
|
|
|
|
|
|
|
namespace Piwigo.Client;
|
|
|
|
|
|
|
|
public class ImageApi : IImageApi
|
|
|
|
{
|
2022-10-22 22:38:25 +02:00
|
|
|
private const string DateFormat = "yyyy-MM-dd";
|
|
|
|
private const string DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
|
|
|
|
|
2022-10-21 00:23:54 +02:00
|
|
|
private readonly IPiwigoContext _context;
|
|
|
|
private readonly ILogger<ImageApi> _logger;
|
|
|
|
|
|
|
|
public ImageApi(IPiwigoContext context, ILogger<ImageApi> logger)
|
|
|
|
{
|
|
|
|
_context = context ?? throw new ArgumentNullException(nameof(context));
|
|
|
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
|
|
|
}
|
|
|
|
|
2022-10-22 23:42:12 +02:00
|
|
|
public async Task<int> AddCommentAsync(int imageId, string? author, string content, string key, CancellationToken cancellationToken = default)
|
|
|
|
{
|
|
|
|
var formParams = new Dictionary<string, string>
|
|
|
|
{
|
|
|
|
{ "image_id", imageId.ToString() },
|
|
|
|
{ "content", content },
|
|
|
|
{ "key", key }
|
|
|
|
};
|
|
|
|
formParams.AddIfValueNotNull("author", author);
|
2022-10-25 17:19:13 +02:00
|
|
|
|
2022-10-22 23:42:12 +02:00
|
|
|
var response = await _context.PostAsync<PiwigoResponse<CommentAdded>>(_logger, "pwg.images.addComment", formParams, cancellationToken);
|
|
|
|
|
|
|
|
return response.Result.Comment.Id;
|
|
|
|
}
|
|
|
|
|
2022-10-22 20:24:12 +02:00
|
|
|
public async Task AddChunkAsync(byte[] data, string originalSum, int position, CancellationToken cancellationToken = default)
|
|
|
|
{
|
|
|
|
var base64Data = Convert.ToBase64String(data);
|
|
|
|
|
|
|
|
var formParams = new Dictionary<string, string>
|
|
|
|
{
|
|
|
|
{ "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<PiwigoResponse>(_logger, "pwg.images.addChunk", formParams, cancellationToken);
|
|
|
|
}
|
|
|
|
|
2022-10-22 22:42:09 +02:00
|
|
|
public Task<ImageUploaded> AddAsync(ImageUpload imageUpload, CancellationToken cancellationToken = default)
|
2022-10-22 22:38:25 +02:00
|
|
|
{
|
2022-10-22 22:42:09 +02:00
|
|
|
return AddOrUpdateAsync(null, imageUpload, cancellationToken);
|
|
|
|
}
|
2022-10-22 22:38:25 +02:00
|
|
|
|
2022-10-22 22:42:09 +02:00
|
|
|
public Task<ImageUploaded> UpdateAsync(int imageId, ImageUpload imageUpload, CancellationToken cancellationToken = default)
|
|
|
|
{
|
|
|
|
return AddOrUpdateAsync(imageId, imageUpload, cancellationToken);
|
2022-10-22 22:38:25 +02:00
|
|
|
}
|
|
|
|
|
2022-10-22 23:20:26 +02:00
|
|
|
public async Task<Image> GetInfoAsync(int imageId, int? commentsPage, int? commentsPerPage, CancellationToken cancellationToken = default)
|
|
|
|
{
|
|
|
|
var formParams = new Dictionary<string, string>
|
|
|
|
{
|
|
|
|
{ "image_id", imageId.ToString() }
|
|
|
|
};
|
|
|
|
formParams.AddIfValueNotNull("comments_page", commentsPage?.ToString());
|
|
|
|
formParams.AddIfValueNotNull("comments_per_page", commentsPerPage?.ToString());
|
|
|
|
|
|
|
|
var response = await _context.PostAsync<PiwigoResponse<Image>>(_logger, "pwg.images.getInfo", formParams, cancellationToken);
|
|
|
|
return response.Result;
|
|
|
|
}
|
|
|
|
|
2022-10-22 20:36:20 +02:00
|
|
|
public async Task<bool> ReadyForUploadAsync(CancellationToken cancellationToken = default)
|
|
|
|
{
|
|
|
|
var response = await _context.PostAsync<PiwigoResponse<CheckUpload>>(_logger, "pwg.images.checkUpload", new Dictionary<string, string>(), cancellationToken);
|
|
|
|
return response.Result.IsReady;
|
|
|
|
}
|
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
public async Task<ImageCheckStatus> CheckImageAsync(int imageId, string md5Sum, CancellationToken cancellationToken = default)
|
2022-10-21 00:23:54 +02:00
|
|
|
{
|
2022-10-25 17:19:13 +02:00
|
|
|
var formParams = new Dictionary<string, string>
|
2022-10-21 00:23:54 +02:00
|
|
|
{
|
2022-10-25 17:19:13 +02:00
|
|
|
{ "image_id", imageId.ToString() },
|
|
|
|
{ "file_sum", md5Sum }
|
2022-10-21 00:23:54 +02:00
|
|
|
};
|
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
var response = await _context.PostAsync<PiwigoResponse<CheckFilesResult>>(_logger, "pwg.images.checkFiles", formParams, cancellationToken);
|
|
|
|
|
|
|
|
return response.Result.ToImageCheckStatus();
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<bool> DeleteAsync(int imageId, string apiToken, CancellationToken cancellationToken = default)
|
|
|
|
{
|
2022-10-21 00:23:54 +02:00
|
|
|
var formParams = new Dictionary<string, string>
|
|
|
|
{
|
2022-10-25 17:19:13 +02:00
|
|
|
{ "image_id", imageId.ToString() },
|
|
|
|
{ "pwg_token", apiToken }
|
2022-10-21 00:23:54 +02:00
|
|
|
};
|
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
var response = await _context.PostAsync<PiwigoResponse<bool>>(_logger, "pwg.images.delete", formParams, cancellationToken);
|
2022-10-21 00:23:54 +02:00
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
return response.Result;
|
|
|
|
}
|
2022-10-21 00:23:54 +02:00
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
public async Task<OrphanImagesDeleted> DeleteOrphansAsync(string apiToken, int? blockSize = null, CancellationToken cancellationToken = default)
|
|
|
|
{
|
|
|
|
var formParams = new Dictionary<string, string>
|
2022-10-21 00:23:54 +02:00
|
|
|
{
|
2022-10-25 17:19:13 +02:00
|
|
|
{ "pwg_token", apiToken }
|
|
|
|
};
|
|
|
|
formParams.AddIfValueNotNull("block_size", blockSize?.ToString());
|
2022-10-21 00:23:54 +02:00
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
var response = await _context.PostAsync<PiwigoResponse<OrphanImagesDeleted>>(_logger, "pwg.images.deleteOrphans", formParams, cancellationToken);
|
|
|
|
|
|
|
|
return response.Result;
|
|
|
|
}
|
2022-10-21 00:23:54 +02:00
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
public async Task<IReadOnlyDictionary<string, int?>> ExistsByMd5SumsAsync(IEnumerable<string> md5Sums, CancellationToken cancellationToken = default)
|
|
|
|
{
|
|
|
|
var formParams = new Dictionary<string, string>
|
2022-10-21 00:23:54 +02:00
|
|
|
{
|
2022-10-25 17:19:13 +02:00
|
|
|
{ "md5sum_list", string.Join(",", md5Sums) }
|
|
|
|
};
|
2022-10-21 00:23:54 +02:00
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
var response = await _context.PostAsync<PiwigoResponse<Dictionary<string, int?>>>(_logger, "pwg.images.exist", formParams, cancellationToken);
|
|
|
|
|
|
|
|
return response.Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<ImageRating> RateAsync(int imageId, int rate, CancellationToken cancellationToken = default)
|
|
|
|
{
|
|
|
|
var formParams = new Dictionary<string, string>
|
2022-10-21 00:23:54 +02:00
|
|
|
{
|
2022-10-25 17:19:13 +02:00
|
|
|
{ "image_id", imageId.ToString() },
|
|
|
|
{ "rate", rate.ToString() }
|
|
|
|
};
|
2022-10-21 00:23:54 +02:00
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
var response = await _context.PostAsync<PiwigoResponse<ImageRating>>(_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
|
2022-10-21 00:23:54 +02:00
|
|
|
{
|
2022-10-25 17:19:13 +02:00
|
|
|
ValueUpdateMode.Append => "fill_if_empty",
|
|
|
|
ValueUpdateMode.Replace => "replace",
|
|
|
|
_ => throw new ArgumentOutOfRangeException(nameof(singleValueMode), singleValueMode, null)
|
|
|
|
};
|
2022-10-21 00:23:54 +02:00
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
var multiMode = multiValueMode switch
|
2022-10-21 00:23:54 +02:00
|
|
|
{
|
2022-10-25 17:19:13 +02:00
|
|
|
ValueUpdateMode.Append => "append",
|
|
|
|
ValueUpdateMode.Replace => "replace",
|
|
|
|
_ => throw new ArgumentOutOfRangeException(nameof(singleValueMode), singleValueMode, null)
|
|
|
|
};
|
2022-10-21 00:23:54 +02:00
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
var formParams = new Dictionary<string, string>
|
2022-10-21 00:23:54 +02:00
|
|
|
{
|
2022-10-25 17:19:13 +02:00
|
|
|
{ "image_id", imageId.ToString() },
|
|
|
|
{ "single_value_mode", singleMode },
|
|
|
|
{ "multiple_value_mode", multiMode }
|
|
|
|
};
|
|
|
|
|
|
|
|
formParams.AddIfValueNotNull("file", imageInfo.FileName);
|
|
|
|
AddImageInfoToForm(formParams, imageInfo);
|
2022-10-21 00:23:54 +02:00
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
await _context.PostAsync<PiwigoResponse>(_logger, "pwg.images.setInfo", formParams, cancellationToken);
|
|
|
|
}
|
|
|
|
|
|
|
|
public async Task<PagedImages> GetImagesAsync(int albumId, bool recursive, ImagePagingInfo page, ImageFilter filter, ImageOrder order = ImageOrder.Name,
|
|
|
|
CancellationToken cancellationToken = default)
|
|
|
|
{
|
|
|
|
var orderValue = order switch
|
2022-10-21 00:23:54 +02:00
|
|
|
{
|
2022-10-25 17:19:13 +02:00
|
|
|
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)
|
|
|
|
};
|
2022-10-21 00:23:54 +02:00
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
var formParams = new Dictionary<string, string>
|
2022-10-21 00:23:54 +02:00
|
|
|
{
|
2022-10-25 17:19:13 +02:00
|
|
|
{ "cat_id", albumId.ToString() },
|
|
|
|
{ "recursive", recursive.ToString() },
|
|
|
|
{ "per_page", page.PageSize.ToString() },
|
|
|
|
{ "page", page.Page.ToString() },
|
|
|
|
{ "order", orderValue }
|
|
|
|
};
|
|
|
|
|
|
|
|
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));
|
2022-10-21 00:23:54 +02:00
|
|
|
|
|
|
|
var response = await _context.PostAsync<PiwigoResponse<PagedImages>>(_logger, "pwg.categories.getImages", formParams, cancellationToken);
|
|
|
|
return response.Result;
|
|
|
|
}
|
2022-10-22 22:42:09 +02:00
|
|
|
|
|
|
|
private async Task<ImageUploaded> AddOrUpdateAsync(int? imageId, ImageUpload imageUpload, CancellationToken cancellationToken)
|
|
|
|
{
|
|
|
|
var formParams = new Dictionary<string, string>
|
|
|
|
{
|
|
|
|
{ "original_sum", imageUpload.OriginalSum },
|
|
|
|
{ "check_uniqueness", "true" }
|
|
|
|
};
|
|
|
|
|
2022-10-25 17:19:13 +02:00
|
|
|
formParams.AddIfValueNotNull("original_filename", imageUpload.FileName);
|
|
|
|
AddImageInfoToForm(formParams, imageUpload);
|
2022-10-22 22:42:09 +02:00
|
|
|
formParams.AddIfValueNotNull("image_id", imageId?.ToString());
|
|
|
|
|
|
|
|
var response = await _context.PostAsync<PiwigoResponse<ImageUploaded>>(_logger, "pwg.images.add", formParams, cancellationToken);
|
|
|
|
|
|
|
|
return response.Result;
|
|
|
|
}
|
2022-10-25 17:19:13 +02:00
|
|
|
|
|
|
|
private static void AddImageInfoToForm(IDictionary<string, string> 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);
|
|
|
|
}
|
2022-10-21 00:23:54 +02:00
|
|
|
}
|