Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardised names #55

Merged
merged 2 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 8 additions & 16 deletions src/TinyPNG/AmazonS3Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,21 @@

namespace TinyPng
{
public class AmazonS3Configuration
public class AmazonS3Configuration(string awsAccessKeyId,
string awsSecretAccessKey,
string defaultBucket,
string defaultRegion)
{
[JsonPropertyName("service")]
public const string Service = "s3";

public AmazonS3Configuration(string awsAccessKeyId,
string awsSecretAccessKey,
string defaultBucket,
string defaultRegion)
{
AwsAccessKeyId = awsAccessKeyId;
AwsSecretAccessKey = awsSecretAccessKey;
Bucket = defaultBucket;
Region = defaultRegion;
}

[JsonPropertyName("aws_access_key_id")]
public string AwsAccessKeyId { get; }
public string AwsAccessKeyId { get; } = awsAccessKeyId;
[JsonPropertyName("aws_secret_access_key")]
public string AwsSecretAccessKey { get; }
public string Region { get; set; }
public string AwsSecretAccessKey { get; } = awsSecretAccessKey;
public string Region { get; set; } = defaultRegion;
[JsonIgnore]
public string Bucket { get; set; }
public string Bucket { get; set; } = defaultBucket;
[JsonIgnore]
public string Path { get; set; }

Expand Down
31 changes: 8 additions & 23 deletions src/TinyPNG/CustomJsonStringEnumConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,13 @@ namespace TinyPng
/// Pinched from https://stackoverflow.com/questions/59059989/system-text-json-how-do-i-specify-a-custom-name-for-an-enum-value
/// This is because System.Text.Json doesn't support EnumMemberAttribute or a way to customise what an Enum value is serialised as.
/// </summary>
internal class CustomJsonStringEnumConverter : JsonConverterFactory
internal class CustomJsonStringEnumConverter(JsonNamingPolicy namingPolicy = null, bool allowIntegerValues = true) : JsonConverterFactory
{
private readonly JsonNamingPolicy namingPolicy;
private readonly bool allowIntegerValues;
private readonly JsonStringEnumConverter baseConverter;
private readonly JsonStringEnumConverter _baseConverter = new(namingPolicy, allowIntegerValues);

public CustomJsonStringEnumConverter() : this(null, true) { }

public CustomJsonStringEnumConverter(JsonNamingPolicy namingPolicy = null, bool allowIntegerValues = true)
{
this.namingPolicy = namingPolicy;
this.allowIntegerValues = allowIntegerValues;
this.baseConverter = new JsonStringEnumConverter(namingPolicy, allowIntegerValues);
}

public override bool CanConvert(Type typeToConvert) => baseConverter.CanConvert(typeToConvert);
public override bool CanConvert(Type typeToConvert) => _baseConverter.CanConvert(typeToConvert);

public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
Expand All @@ -42,26 +33,20 @@ public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializer
}
else
{
return baseConverter.CreateConverter(typeToConvert, options);
return _baseConverter.CreateConverter(typeToConvert, options);
}
}
}

public class JsonNamingPolicyDecorator : JsonNamingPolicy
public class JsonNamingPolicyDecorator(JsonNamingPolicy underlyingNamingPolicy) : JsonNamingPolicy
{
readonly JsonNamingPolicy underlyingNamingPolicy;

public JsonNamingPolicyDecorator(JsonNamingPolicy underlyingNamingPolicy) => this.underlyingNamingPolicy = underlyingNamingPolicy;

public override string ConvertName(string name) => underlyingNamingPolicy == null ? name : underlyingNamingPolicy.ConvertName(name);
}

internal class DictionaryLookupNamingPolicy : JsonNamingPolicyDecorator
internal class DictionaryLookupNamingPolicy(Dictionary<string, string> dictionary, JsonNamingPolicy underlyingNamingPolicy) : JsonNamingPolicyDecorator(underlyingNamingPolicy)
{
readonly Dictionary<string, string> dictionary;

public DictionaryLookupNamingPolicy(Dictionary<string, string> dictionary, JsonNamingPolicy underlyingNamingPolicy) : base(underlyingNamingPolicy) => this.dictionary = dictionary ?? throw new ArgumentNullException();
readonly Dictionary<string, string> _dictionary = dictionary ?? throw new ArgumentNullException();

public override string ConvertName(string name) => dictionary.TryGetValue(name, out var value) ? value : base.ConvertName(name);
public override string ConvertName(string name) => _dictionary.TryGetValue(name, out var value) ? value : base.ConvertName(name);
}
}
6 changes: 3 additions & 3 deletions src/TinyPNG/Extensions/ConvertExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,20 @@ public static async Task<TinyPngConvertResponse> Convert(this Task<TinyPngCompre

TinyPngCompressResponse compressResponse = await result;

string requestBody = JsonSerializer.Serialize(new { convert = new { type = convertOperation } }, TinyPngClient.JsonOptions);
string requestBody = JsonSerializer.Serialize(new { convert = new { type = convertOperation } }, TinyPngClient._jsonOptions);

HttpRequestMessage msg = new(HttpMethod.Post, compressResponse.Output.Url)
{
Content = new StringContent(requestBody, Encoding.UTF8, "application/json")
};

HttpResponseMessage response = await compressResponse.HttpClient.SendAsync(msg);
HttpResponseMessage response = await compressResponse._httpClient.SendAsync(msg);
if (response.IsSuccessStatusCode)
{
return new TinyPngConvertResponse(response);
}

ApiErrorResponse errorMsg = await JsonSerializer.DeserializeAsync<ApiErrorResponse>(await response.Content.ReadAsStreamAsync(), TinyPngClient.JsonOptions);
ApiErrorResponse errorMsg = await JsonSerializer.DeserializeAsync<ApiErrorResponse>(await response.Content.ReadAsStreamAsync(), TinyPngClient._jsonOptions);
throw new TinyPngApiException((int)response.StatusCode, response.ReasonPhrase, errorMsg.Error, errorMsg.Message);


Expand Down
12 changes: 6 additions & 6 deletions src/TinyPNG/Extensions/DownloadExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace TinyPng;

public static class DownloadExtensions
{
private const string JpegType = "image/jpeg";
private const string _jpegType = "image/jpeg";

/// <summary>
/// Downloads the result of a TinyPng Compression operation
Expand Down Expand Up @@ -44,7 +44,7 @@ public static async Task<TinyPngImageResponse> Download(this TinyPngCompressResp
Content = CreateContent(metadata, compressResponse.Output.Type)
};

var response = await compressResponse.HttpClient.SendAsync(msg).ConfigureAwait(false);
var response = await compressResponse._httpClient.SendAsync(msg).ConfigureAwait(false);

if (response.IsSuccessStatusCode)
{
Expand All @@ -68,15 +68,15 @@ private static HttpContent CreateContent(PreserveMetadata metadata, string type)
}
if (metadata.HasFlag(PreserveMetadata.Creation))
{
if (type != JpegType)
throw new InvalidOperationException($"Creation metadata can only be preserved with type {JpegType}");
if (type != _jpegType)
throw new InvalidOperationException($"Creation metadata can only be preserved with type {_jpegType}");

preserve.Add("creation");
}
if (metadata.HasFlag(PreserveMetadata.Location))
{
if (type != JpegType)
throw new InvalidOperationException($"Location metadata can only be preserved with type {JpegType}");
if (type != _jpegType)
throw new InvalidOperationException($"Location metadata can only be preserved with type {_jpegType}");

preserve.Add("location");
}
Expand Down
6 changes: 3 additions & 3 deletions src/TinyPNG/Extensions/ResizeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@ public static async Task<TinyPngResizeResponse> Resize(this Task<TinyPngCompress

TinyPngCompressResponse compressResponse = await result;

string requestBody = JsonSerializer.Serialize(new { resize = resizeOperation }, TinyPngClient.JsonOptions);
string requestBody = JsonSerializer.Serialize(new { resize = resizeOperation }, TinyPngClient._jsonOptions);

HttpRequestMessage msg = new(HttpMethod.Post, compressResponse.Output.Url)
{
Content = new StringContent(requestBody, System.Text.Encoding.UTF8, "application/json")
};

HttpResponseMessage response = await compressResponse.HttpClient.SendAsync(msg);
HttpResponseMessage response = await compressResponse._httpClient.SendAsync(msg);
if (response.IsSuccessStatusCode)
{
return new TinyPngResizeResponse(response);
}

ApiErrorResponse errorMsg = await JsonSerializer.DeserializeAsync<ApiErrorResponse>(await response.Content.ReadAsStreamAsync(), TinyPngClient.JsonOptions);
ApiErrorResponse errorMsg = await JsonSerializer.DeserializeAsync<ApiErrorResponse>(await response.Content.ReadAsStreamAsync(), TinyPngClient._jsonOptions);
throw new TinyPngApiException((int)response.StatusCode, response.ReasonPhrase, errorMsg.Error, errorMsg.Message);
}

Expand Down
3 changes: 1 addition & 2 deletions src/TinyPNG/ResizeOperations/FitResizeOperation.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
namespace TinyPng.ResizeOperations;

public class FitResizeOperation : ResizeOperation
public class FitResizeOperation(int width, int height) : ResizeOperation(ResizeType.Fit, width, height)
{
public FitResizeOperation(int width, int height) : base(ResizeType.Fit, width, height) { }
}
3 changes: 1 addition & 2 deletions src/TinyPNG/ResizeOperations/ScaleHeightResizeOperation.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
namespace TinyPng.ResizeOperations;

public class ScaleHeightResizeOperation : ResizeOperation
public class ScaleHeightResizeOperation(int height) : ResizeOperation(ResizeType.Scale, null, height)
{
public ScaleHeightResizeOperation(int height) : base(ResizeType.Scale, null, height) { }
}
3 changes: 1 addition & 2 deletions src/TinyPNG/ResizeOperations/ScaleWidthResizeOperation.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
namespace TinyPng.ResizeOperations;

public class ScaleWidthResizeOperation : ResizeOperation
public class ScaleWidthResizeOperation(int width) : ResizeOperation(ResizeType.Scale, width, null)
{
public ScaleWidthResizeOperation(int width) : base(ResizeType.Scale, width, null) { }
}
6 changes: 3 additions & 3 deletions src/TinyPNG/Responses/TinyPngCompressResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ public class TinyPngCompressResponse : TinyPngResponse
public TinyPngApiOutput Output { get; private set; }
public TinyPngApiResult ApiResult { get; private set; }

internal readonly HttpClient HttpClient;
internal readonly HttpClient _httpClient;

public TinyPngCompressResponse(HttpResponseMessage msg, HttpClient httpClient) : base(msg)
{
HttpClient = httpClient;
_httpClient = httpClient;

//this is a cute trick to handle async in a ctor and avoid deadlocks
ApiResult = Task.Run(() => Deserialize(msg)).GetAwaiter().GetResult();
Expand All @@ -24,6 +24,6 @@ public TinyPngCompressResponse(HttpResponseMessage msg, HttpClient httpClient) :
}
private async Task<TinyPngApiResult> Deserialize(HttpResponseMessage response)
{
return await JsonSerializer.DeserializeAsync<TinyPngApiResult>(await response.Content.ReadAsStreamAsync(), TinyPngClient.JsonOptions);
return await JsonSerializer.DeserializeAsync<TinyPngApiResult>(await response.Content.ReadAsStreamAsync(), TinyPngClient._jsonOptions);
}
}
6 changes: 1 addition & 5 deletions src/TinyPNG/Responses/TinyPngConvertResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@
using System.Net.Http;

namespace TinyPng.Responses;
public class TinyPngConvertResponse : TinyPngImageResponse
public class TinyPngConvertResponse(HttpResponseMessage msg) : TinyPngImageResponse(msg)
{
public TinyPngConvertResponse(HttpResponseMessage msg) : base(msg)
{
}

public string ContentType => HttpResponseMessage.Content.Headers.ContentType.MediaType;
public string ImageHeight => HttpResponseMessage.Content.Headers.GetValues("Image-Height").FirstOrDefault();
public string ImageWidth => HttpResponseMessage.Content.Headers.GetValues("Image-Width").FirstOrDefault();
Expand Down
5 changes: 1 addition & 4 deletions src/TinyPNG/Responses/TinyPngImageResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ namespace TinyPng.Responses;
/// <summary>
/// This is a response which contains actual image data
/// </summary>
public class TinyPngImageResponse : TinyPngResponse
public class TinyPngImageResponse(HttpResponseMessage msg) : TinyPngResponse(msg)
{
public TinyPngImageResponse(HttpResponseMessage msg) : base(msg)
{
}
}
6 changes: 1 addition & 5 deletions src/TinyPNG/Responses/TinyPngResizeResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

namespace TinyPng.Responses;

public class TinyPngResizeResponse : TinyPngImageResponse
public class TinyPngResizeResponse(HttpResponseMessage msg) : TinyPngImageResponse(msg)
{
public TinyPngResizeResponse(HttpResponseMessage msg) : base(msg)
{

}
}
7 changes: 3 additions & 4 deletions src/TinyPNG/Responses/TinyPngResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@ public class TinyPngResponse
{
internal HttpResponseMessage HttpResponseMessage { get; }

private readonly int compressionCount;

public int CompressionCount => compressionCount;
private readonly int _compressionCount;

public int CompressionCount => _compressionCount;


protected TinyPngResponse(HttpResponseMessage msg)
{
if (msg.Headers.TryGetValues("Compression-Count", out IEnumerable<string> compressionCountHeaders))
{
int.TryParse(compressionCountHeaders.First(), out compressionCount);
int.TryParse(compressionCountHeaders.First(), out _compressionCount);
}
HttpResponseMessage = msg;
}
Expand Down
3 changes: 1 addition & 2 deletions src/TinyPNG/TinyPNG.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@


<!-- Source link support -->
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="System.Text.Json" Version="7.0.3" />
<PackageReference Include="System.Text.Json" Version="8.0.3" />

</ItemGroup>

Expand Down
24 changes: 12 additions & 12 deletions src/TinyPNG/TinyPngClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ namespace TinyPng;

public class TinyPngClient
{
private const string ApiEndpoint = "https://api.tinify.com/shrink";
private const string _apiEndpoint = "https://api.tinify.com/shrink";

private readonly HttpClient HttpClient;
internal static readonly JsonSerializerOptions JsonOptions;
private readonly HttpClient _httpClient;
internal static readonly JsonSerializerOptions _jsonOptions;

/// <summary>
/// Configures the client to use these AmazonS3 settings when storing images in S3
Expand All @@ -28,14 +28,14 @@ public class TinyPngClient
static TinyPngClient()
{
//configure json settings for camelCase.
JsonOptions = new JsonSerializerOptions
_jsonOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};

JsonOptions.Converters.Add(new CustomJsonStringEnumConverter(JsonNamingPolicy.CamelCase));
_jsonOptions.Converters.Add(new CustomJsonStringEnumConverter(JsonNamingPolicy.CamelCase));

}

Expand All @@ -49,7 +49,7 @@ public TinyPngClient(string apiKey, HttpClient httpClient = null)
if (string.IsNullOrEmpty(apiKey))
throw new ArgumentNullException(nameof(apiKey));

HttpClient = httpClient ?? new HttpClient();
_httpClient = httpClient ?? new HttpClient();

ConfigureHttpClient(apiKey);
}
Expand All @@ -62,7 +62,7 @@ private void ConfigureHttpClient(string apiKey)
var apiKeyEncoded = Convert.ToBase64String(authByteArray);

//add auth to the default outgoing headers.
HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("basic", apiKeyEncoded);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("basic", apiKeyEncoded);
}

/// <summary>
Expand Down Expand Up @@ -133,16 +133,16 @@ public Task<TinyPngCompressResponse> Compress(Uri url)
return CompressInternal(CreateContent(url));

static HttpContent CreateContent(Uri source) => new StringContent(
JsonSerializer.Serialize(new { source = new { url = source } }, JsonOptions),
JsonSerializer.Serialize(new { source = new { url = source } }, _jsonOptions),
Encoding.UTF8, "application/json");
}

private async Task<TinyPngCompressResponse> CompressInternal(HttpContent contentData)
{
var response = await HttpClient.PostAsync(ApiEndpoint, contentData).ConfigureAwait(false);
var response = await _httpClient.PostAsync(_apiEndpoint, contentData).ConfigureAwait(false);

if (response.IsSuccessStatusCode)
return new TinyPngCompressResponse(response, HttpClient);
return new TinyPngCompressResponse(response, _httpClient);

var errorMsg = await JsonSerializer.DeserializeAsync<ApiErrorResponse>(await response.Content.ReadAsStreamAsync().ConfigureAwait(false));
throw new TinyPngApiException((int)response.StatusCode, response.ReasonPhrase, errorMsg.Error, errorMsg.Message);
Expand All @@ -166,13 +166,13 @@ public async Task<Uri> SaveCompressedImageToAmazonS3(TinyPngCompressResponse res

amazonSettings.Path = path;

var amazonSettingsAsJson = JsonSerializer.Serialize(new { store = amazonSettings }, JsonOptions);
var amazonSettingsAsJson = JsonSerializer.Serialize(new { store = amazonSettings }, _jsonOptions);

var msg = new HttpRequestMessage(HttpMethod.Post, result.Output.Url)
{
Content = new StringContent(amazonSettingsAsJson, System.Text.Encoding.UTF8, "application/json")
};
var response = await HttpClient.SendAsync(msg).ConfigureAwait(false);
var response = await _httpClient.SendAsync(msg).ConfigureAwait(false);

if (response.IsSuccessStatusCode)
{
Expand Down
4 changes: 2 additions & 2 deletions tests/TinyPng.Tests/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public static FakeResponseHandler CompressAndFail(this FakeResponseHandler fakeR

public static FakeResponseHandler Download(this FakeResponseHandler fakeResponse)
{
FileStream compressedCatStream = File.OpenRead(TinyPngTests.CompressedCat);
FileStream compressedCatStream = File.OpenRead(TinyPngTests._compressedCat);
HttpResponseMessage outputResponseMessage = new()
{
Content = new StreamContent(compressedCatStream),
Expand All @@ -78,7 +78,7 @@ public static FakeResponseHandler DownloadAndFail(this FakeResponseHandler fakeR

public static FakeResponseHandler Resize(this FakeResponseHandler fakeResponse)
{
FileStream resizedCatStream = File.OpenRead(TinyPngTests.ResizedCat);
FileStream resizedCatStream = File.OpenRead(TinyPngTests._resizedCat);
HttpResponseMessage resizeMessage = new()
{
StatusCode = System.Net.HttpStatusCode.OK,
Expand Down
Loading
Loading