From 29cda815a8e2c7668c16bd60dc8fc7abcf9e21ba Mon Sep 17 00:00:00 2001 From: Kim Ipsen Date: Thu, 21 Dec 2023 14:27:04 +0100 Subject: [PATCH] Update flurl and dotnet --- src/INemligClient.cs | 27 +++---- src/IResponse.cs | 179 ++++++++++++++++++++--------------------- src/Model.cs | 25 +++--- src/NemligClient.cs | 88 ++++++++------------ src/NemligSharp.csproj | 4 +- src/Payloads.cs | 7 +- src/Responses.cs | 21 +++-- 7 files changed, 162 insertions(+), 189 deletions(-) diff --git a/src/INemligClient.cs b/src/INemligClient.cs index 77103e4..9fe89eb 100644 --- a/src/INemligClient.cs +++ b/src/INemligClient.cs @@ -1,26 +1,25 @@ using System.Threading.Tasks; -namespace NemligSharp +namespace NemligSharp; + +public interface INemligClient { - public interface INemligClient - { - // search (GET, QueryString, "sæbe"/"s%C3%A6be"): search?query=s%C3%A6be&take=20&skip=0&recipeCount=2&search=s%C3%A6be&sortorder=default - //ISearchResponse SearchAsync(string searchString); + // search (GET, QueryString, "sæbe"/"s%C3%A6be"): search?query=s%C3%A6be&take=20&skip=0&recipeCount=2&search=s%C3%A6be&sortorder=default + //ISearchResponse SearchAsync(string searchString); - // quick (GET, QueryString, "sæbe"): quick?query=s%C3%A6be&take=20&skip=0&recipeCount=2& + // quick (GET, QueryString, "sæbe"): quick?query=s%C3%A6be&take=20&skip=0&recipeCount=2& - Task LoginAsync(string userName, string password); + Task LoginAsync(string userName, string password); - Task GetCurrentUserAsync(); + Task GetCurrentUserAsync(); - Task GetOrderHistoryAsync(int skip, int take); + Task GetOrderHistoryAsync(int skip, int take); - Task GetOrderAsync(int orderId); + Task GetOrderAsync(int orderId); - Task GetShoppingListsAsync(int skip, int take); + Task GetShoppingListsAsync(int skip, int take); - Task GetShoppingListAsync(int shoppingListId); + Task GetShoppingListAsync(int shoppingListId); - Task GetCurrentBasketAsync(); - } + Task GetCurrentBasketAsync(); } \ No newline at end of file diff --git a/src/IResponse.cs b/src/IResponse.cs index caf0b53..9d7a61e 100644 --- a/src/IResponse.cs +++ b/src/IResponse.cs @@ -1,103 +1,102 @@ using System; -namespace NemligSharp +namespace NemligSharp; + +public interface IResponse { - public interface IResponse - { - int StatusCode { get; } - } + int StatusCode { get; } +} - public interface ISearchResponse : IResponse - { - } +public interface ISearchResponse : IResponse +{ +} - public interface ILoginResponse : IResponse - { - // "TimeslotUtc": "2021011715-60-960", +public interface ILoginResponse : IResponse +{ + // "TimeslotUtc": "2021011715-60-960", - string RedirectUrl { get; } - bool MergeSuccessful { get; } - bool ZipCodeFiffers { get; } - int DeliveryZoneId { get; } - GdprSettings GdprSettings { get; } - bool IsExternalLogin { get; } - bool IsFirstLogin { get; } - } + string RedirectUrl { get; } + bool MergeSuccessful { get; } + bool ZipCodeFiffers { get; } + int DeliveryZoneId { get; } + GdprSettings GdprSettings { get; } + bool IsExternalLogin { get; } + bool IsFirstLogin { get; } +} - public interface ICurrentUserResponse : IResponse - { - string DebitorId { get; } - string Email { get; } - int MemberType { get; } - string MessageToDriver { get; } - Address DeliveryAddress { get; } - Address InvoiceAddress { get; } - DriverInformation DriverInformation { get; } - bool IsUnattendedTutorialShown { get; } - int DefaultDeliveryType { get; } - bool AddressesAreEqual { get; } - string EAN { get; } - string CVR { get; } - } +public interface ICurrentUserResponse : IResponse +{ + string DebitorId { get; } + string Email { get; } + int MemberType { get; } + string MessageToDriver { get; } + Address DeliveryAddress { get; } + Address InvoiceAddress { get; } + DriverInformation DriverInformation { get; } + bool IsUnattendedTutorialShown { get; } + int DefaultDeliveryType { get; } + bool AddressesAreEqual { get; } + string EAN { get; } + string CVR { get; } +} - public interface IOrderHistoryResponse : IResponse - { - int NumberOfPages { get; } - Order[] Orders { get; } - } +public interface IOrderHistoryResponse : IResponse +{ + int NumberOfPages { get; } + Order[] Orders { get; } +} - public interface IOrderResponse : IResponse - { - OrderLine[] Lines { get; } - string OrderNumber { get; } - decimal SubTotal { get; } - decimal DepositPrice { get; } - decimal ShippingPrice { get; } - decimal PackagingPrice { get; } - decimal TransactionFee { get; } - decimal TotalVatAmount { get; } - decimal Bonus { get; } - decimal AddedToAccount { get; } - decimal CouponDiscount { get; } - decimal TotalProductDiscountPrice { get; } - decimal TotalProductDiscount { get; } - decimal Total { get; } - CouponLine[] CouponLines { get; } - string Notes { get; } - string UnattendedNotes { get; } - string PlacementMessage { get; } - string DoorCode { get; } - int TimeslotDuration { get; } - int Id { get; } - string Email { get; } - int NumberOfProducts { get; } - int NumberOfPacks { get; } - int NumberOfDeposits { get; } - } +public interface IOrderResponse : IResponse +{ + OrderLine[] Lines { get; } + string OrderNumber { get; } + decimal SubTotal { get; } + decimal DepositPrice { get; } + decimal ShippingPrice { get; } + decimal PackagingPrice { get; } + decimal TransactionFee { get; } + decimal TotalVatAmount { get; } + decimal Bonus { get; } + decimal AddedToAccount { get; } + decimal CouponDiscount { get; } + decimal TotalProductDiscountPrice { get; } + decimal TotalProductDiscount { get; } + decimal Total { get; } + CouponLine[] CouponLines { get; } + string Notes { get; } + string UnattendedNotes { get; } + string PlacementMessage { get; } + string DoorCode { get; } + int TimeslotDuration { get; } + int Id { get; } + string Email { get; } + int NumberOfProducts { get; } + int NumberOfPacks { get; } + int NumberOfDeposits { get; } +} - public interface IShoppingListsResponse : IResponse - { - int NumberOfPages { get; } - ShoppingList[] ShoppingListOverViewViewModels { get; } - } +public interface IShoppingListsResponse : IResponse +{ + int NumberOfPages { get; } + ShoppingList[] ShoppingListOverViewViewModels { get; } +} - public interface IShoppingListResponse : IResponse - { - int Id { get; } - string Name { get; } - string Url { get; } - bool ContainsDeactivatedData { get; } - int ProductsCount { get; } - decimal TotalAmount { get; } - object[] ValidationFailures { get; } - Product[] Lines { get; } - } +public interface IShoppingListResponse : IResponse +{ + int Id { get; } + string Name { get; } + string Url { get; } + bool ContainsDeactivatedData { get; } + int ProductsCount { get; } + decimal TotalAmount { get; } + object[] ValidationFailures { get; } + Product[] Lines { get; } +} - public interface ICurrentBasketResponse : IResponse - { - string Id { get; } - Guid BasketGuid { get; } - Address InvoiceAddress { get; } - Address DeliveryAddress { get; } - } +public interface ICurrentBasketResponse : IResponse +{ + string Id { get; } + Guid BasketGuid { get; } + Address InvoiceAddress { get; } + Address DeliveryAddress { get; } } \ No newline at end of file diff --git a/src/Model.cs b/src/Model.cs index 82bae0f..85ae933 100644 --- a/src/Model.cs +++ b/src/Model.cs @@ -1,15 +1,14 @@ using System; -namespace NemligSharp -{ - public record Order(string OrderNumber, decimal Total, int Id, DeliveryTime DeliveryTime, string DeliveryAddress, bool IsDeliveryOnWay, int DeliveryType); - public record DeliveryTime(DateTime Start, DateTime End); - public record OrderLine(string GroupName, string ProductNumber, string ProductName, string RecipeId, int Quantity, string Description, decimal AverageItemPrice, decimal Amount); - public record GdprSettings(int NewslettersIntegrationId, int RecipesIntegrationId, int SmsNotificationsIntegrationId, int NemligAdsOnSearchEnginesIntegrationId, int NemligAdsOnOtherSitesIntegrationId, int SurveysIntegrationId); - public record Address(string FirstName, string MiddleName, string LastName, string StreetName, int HouseNumber, string HouseNumberLetter, string Floor, string Side, string Door, int PostalCode, string PostalDistrict, string CompanyName, string MobileNumber, string PhoneNumber, string ContactPerson, bool IsEmptyAddress, string Name); - public record DriverInformation(string AttendedDeliveryNote, string UnattendedDeliveryDoorCode, string UnattendedDeliveryNote, string UnattendedPlacementMessage); - public record ShoppingList(int Id, string Name, string Url, bool ContainsDeactivatedData, int ProductsCount, decimal TotalAmount, int ProductCountInList); - public record Product(decimal ItemPrice, decimal DiscountSavings, int Quantity, string PrimaryImage, bool IsProductDeactivated, decimal ProductsTotalAmount, Availability Availability, int GroupSortOrder, string GroupName, string Id, string Name, string Url, string UnitPrice, decimal UnitPriceCalc, string UnitPriceLabel, bool DiscountItem, string Description, decimal Price, string Campaign, string[] Labels, string ProductSubGroupNumber, string ProductSubGroupName, string ProductCategoryGroupNumber, string ProductCategoryGroupName, string ProductMainGroupNumber, string ProductMainGroupName); - public record Availability(bool IsDeliveryAvailable, bool IsAvailableInStock, string[] ReasonMessageKeys); - public record CouponLine(string Type, string Name, string CouponNumber); -} \ No newline at end of file +namespace NemligSharp; + +public record Order(string OrderNumber, decimal Total, int Id, DeliveryTime DeliveryTime, string DeliveryAddress, bool IsDeliveryOnWay, int DeliveryType); +public record DeliveryTime(DateTime Start, DateTime End); +public record OrderLine(string GroupName, string ProductNumber, string ProductName, string RecipeId, int Quantity, string Description, decimal AverageItemPrice, decimal Amount); +public record GdprSettings(int NewslettersIntegrationId, int RecipesIntegrationId, int SmsNotificationsIntegrationId, int NemligAdsOnSearchEnginesIntegrationId, int NemligAdsOnOtherSitesIntegrationId, int SurveysIntegrationId); +public record Address(string FirstName, string MiddleName, string LastName, string StreetName, int HouseNumber, string HouseNumberLetter, string Floor, string Side, string Door, int PostalCode, string PostalDistrict, string CompanyName, string MobileNumber, string PhoneNumber, string ContactPerson, bool IsEmptyAddress, string Name); +public record DriverInformation(string AttendedDeliveryNote, string UnattendedDeliveryDoorCode, string UnattendedDeliveryNote, string UnattendedPlacementMessage); +public record ShoppingList(int Id, string Name, string Url, bool ContainsDeactivatedData, int ProductsCount, decimal TotalAmount, int ProductCountInList); +public record Product(decimal ItemPrice, decimal DiscountSavings, int Quantity, string PrimaryImage, bool IsProductDeactivated, decimal ProductsTotalAmount, Availability Availability, int GroupSortOrder, string GroupName, string Id, string Name, string Url, string UnitPrice, decimal UnitPriceCalc, string UnitPriceLabel, bool DiscountItem, string Description, decimal Price, string Campaign, string[] Labels, string ProductSubGroupNumber, string ProductSubGroupName, string ProductCategoryGroupNumber, string ProductCategoryGroupName, string ProductMainGroupNumber, string ProductMainGroupName); +public record Availability(bool IsDeliveryAvailable, bool IsAvailableInStock, string[] ReasonMessageKeys); +public record CouponLine(string Type, string Name, string CouponNumber); \ No newline at end of file diff --git a/src/NemligClient.cs b/src/NemligClient.cs index 49ec718..0c52e02 100644 --- a/src/NemligClient.cs +++ b/src/NemligClient.cs @@ -1,72 +1,50 @@ using System.Text.Json; using System.Threading.Tasks; using Flurl.Http; -using Flurl.Http.Configuration; -namespace NemligSharp -{ - public class NemligClient : INemligClient - { - public const string NemligBaseUrl = "https://www.nemlig.com/"; - private readonly IFlurlClient _flurlClient; - private CookieJar _cookieJar = null; +namespace NemligSharp; - public NemligClient(IFlurlClientFactory flurlClientFactory) - { - _flurlClient = flurlClientFactory.Get(NemligBaseUrl); - } +public class NemligClient : INemligClient +{ + public const string NemligBaseUrl = "https://www.nemlig.com/"; + private readonly IFlurlClient _flurlClient = new FlurlClient(NemligBaseUrl); + private CookieJar _cookieJar = null; - public async Task LoginAsync(string userName, string password) - { - var payload = new LoginPayload(userName, password); - var response = await _flurlClient.Request(new string[] { "webapi", "login" }).WithCookies(out var jar).PostJsonAsync(payload).ConfigureAwait(false); - var jsonString = await response.GetStringAsync().ConfigureAwait(false); - var deserialized = JsonSerializer.Deserialize(jsonString); + public async Task LoginAsync(string userName, string password) + { + var payload = new LoginPayload(userName, password); + var response = await _flurlClient.Request("webapi", "login").WithCookies(out var jar).PostJsonAsync(payload).ConfigureAwait(false); + var jsonString = await response.GetStringAsync().ConfigureAwait(false); + var deserialized = JsonSerializer.Deserialize(jsonString); - _cookieJar = jar; + _cookieJar = jar; - return deserialized with { StatusCode = response.StatusCode }; - } + return deserialized with { StatusCode = response.StatusCode }; + } - public async Task GetCurrentUserAsync() - { - return await DoFlurlGet(new string[] { "webapi", "user", "GetCurrentUser" }).ConfigureAwait(false); - } + public async Task GetCurrentUserAsync() => await DoFlurlGet(["webapi", "user", "GetCurrentUser"]).ConfigureAwait(false); - public async Task GetOrderHistoryAsync(int skip, int take) - { - return await DoFlurlGet(new string[] { "webapi", "order", "GetBasicOrderHistory" }, new { skip, take }); - } + public async Task GetOrderHistoryAsync(int skip, int take) + { + return await DoFlurlGet(["webapi", "order", "GetBasicOrderHistory"], new { skip, take }); + } - public async Task GetOrderAsync(int orderId) - { - return await DoFlurlGet(new string[] { "webapi", "order", "GetOrderHistory" }, new { orderNumber = orderId }); - } + public async Task GetOrderAsync(int orderId) => await DoFlurlGet(["webapi", "order", "GetOrderHistory"], new { orderNumber = orderId }); - public async Task GetShoppingListsAsync(int skip, int take) - { - return await DoFlurlGet(new string[] { "webapi", "ShoppingList", "GetShoppingLists" }, new { skip, take }); - } + public async Task GetShoppingListsAsync(int skip, int take) => await DoFlurlGet(["webapi", "ShoppingList", "GetShoppingLists"], new { skip, take }); - public async Task GetShoppingListAsync(int shoppingListId) - { - return await DoFlurlGet(new string[] { "webapi", "ShoppingList", "GetShoppingList" }, new { listId = shoppingListId }); - } + public async Task GetShoppingListAsync(int shoppingListId) => await DoFlurlGet(["webapi", "ShoppingList", "GetShoppingList"], new { listId = shoppingListId }); - public async Task GetCurrentBasketAsync() - { - return await DoFlurlGet(new string[] { "webapi", "basket", "GetBasket" }); - } + public async Task GetCurrentBasketAsync() => await DoFlurlGet(["webapi", "basket", "GetBasket"]); - private async Task DoFlurlGet(string[] pathSegments, object queryParameters = null) - where TResponseImplementation : Response, TResponseInterface - where TResponseInterface : IResponse - { - var response = await _flurlClient.Request(pathSegments).SetQueryParams(queryParameters).WithCookies(_cookieJar).GetAsync().ConfigureAwait(false); - var jsonString = await response.GetStringAsync().ConfigureAwait(false); - var deserialized = JsonSerializer.Deserialize(jsonString); + private async Task DoFlurlGet(string[] pathSegments, object queryParameters = null) + where TResponseImplementation : Response, TResponseInterface + where TResponseInterface : IResponse + { + var response = await _flurlClient.Request(pathSegments).SetQueryParams(queryParameters).WithCookies(_cookieJar).GetAsync().ConfigureAwait(false); + var jsonString = await response.GetStringAsync().ConfigureAwait(false); + var deserialized = JsonSerializer.Deserialize(jsonString); - return deserialized with { StatusCode = response.StatusCode }; - } - } + return deserialized with { StatusCode = response.StatusCode }; + } } \ No newline at end of file diff --git a/src/NemligSharp.csproj b/src/NemligSharp.csproj index f1ff4f8..0c3154e 100644 --- a/src/NemligSharp.csproj +++ b/src/NemligSharp.csproj @@ -1,7 +1,7 @@ - net5.0 + net8.0 https://github.com/kimipsen/NemligSharp/ LICENSE @@ -12,7 +12,7 @@ - + diff --git a/src/Payloads.cs b/src/Payloads.cs index 4385193..6979ad3 100644 --- a/src/Payloads.cs +++ b/src/Payloads.cs @@ -1,4 +1,3 @@ -namespace NemligSharp -{ - internal record LoginPayload(string Username, string Password, bool AutoLogin = false, bool CheckForExistingProducts = true, bool DoMerge = true, bool AppInstalled = false); -} \ No newline at end of file +namespace NemligSharp; + +internal record LoginPayload(string Username, string Password, bool AutoLogin = false, bool CheckForExistingProducts = true, bool DoMerge = true, bool AppInstalled = false); \ No newline at end of file diff --git a/src/Responses.cs b/src/Responses.cs index 7f38900..5990012 100644 --- a/src/Responses.cs +++ b/src/Responses.cs @@ -1,13 +1,12 @@ using System; -namespace NemligSharp -{ - internal record Response(int StatusCode) : IResponse; - internal record LoginResponse(int StatusCode, string RedirectUrl, bool MergeSuccessful, bool ZipCodeFiffers, int DeliveryZoneId, GdprSettings GdprSettings, bool IsExternalLogin, bool IsFirstLogin) : Response(StatusCode), ILoginResponse; - internal record CurrentUserResponse(int StatusCode, string DebitorId, string Email, int MemberType, string MessageToDriver, Address DeliveryAddress, Address InvoiceAddress, DriverInformation DriverInformation, bool IsUnattendedTutorialShown, int DefaultDeliveryType, bool AddressesAreEqual, string EAN, string CVR) : Response(StatusCode), ICurrentUserResponse; - internal record OrderHistoryResponse(int StatusCode, int NumberOfPages, Order[] Orders) : Response(StatusCode), IOrderHistoryResponse; - internal record OrderResponse(int StatusCode, OrderLine[] Lines, string OrderNumber, decimal SubTotal, decimal DepositPrice, decimal ShippingPrice, decimal PackagingPrice, decimal TransactionFee, decimal TotalVatAmount, decimal Bonus, decimal AddedToAccount, decimal CouponDiscount, decimal TotalProductDiscountPrice, decimal TotalProductDiscount, decimal Total, CouponLine[] CouponLines, string Notes, string UnattendedNotes, string PlacementMessage, string DoorCode, int TimeslotDuration, int Id, string Email, int NumberOfProducts, int NumberOfPacks, int NumberOfDeposits) : Response(StatusCode), IOrderResponse; - internal record ShoppingListsResponse(int StatusCode, ShoppingList[] ShoppingListOverViewViewModels, int NumberOfPages) : Response(StatusCode), IShoppingListsResponse; - internal record ShoppingListResponse(int StatusCode, int Id, string Name, string Url, bool ContainsDeactivatedData, int ProductsCount, decimal TotalAmount, object[] ValidationFailures, Product[] Lines) : Response(StatusCode), IShoppingListResponse; - internal record CurrentBasketResponse(int StatusCode, string Id, Guid BasketGuid, Address InvoiceAddress, Address DeliveryAddress) : Response(StatusCode), ICurrentBasketResponse; -} \ No newline at end of file +namespace NemligSharp; + +internal record Response(int StatusCode) : IResponse; +internal record LoginResponse(int StatusCode, string RedirectUrl, bool MergeSuccessful, bool ZipCodeFiffers, int DeliveryZoneId, GdprSettings GdprSettings, bool IsExternalLogin, bool IsFirstLogin) : Response(StatusCode), ILoginResponse; +internal record CurrentUserResponse(int StatusCode, string DebitorId, string Email, int MemberType, string MessageToDriver, Address DeliveryAddress, Address InvoiceAddress, DriverInformation DriverInformation, bool IsUnattendedTutorialShown, int DefaultDeliveryType, bool AddressesAreEqual, string EAN, string CVR) : Response(StatusCode), ICurrentUserResponse; +internal record OrderHistoryResponse(int StatusCode, int NumberOfPages, Order[] Orders) : Response(StatusCode), IOrderHistoryResponse; +internal record OrderResponse(int StatusCode, OrderLine[] Lines, string OrderNumber, decimal SubTotal, decimal DepositPrice, decimal ShippingPrice, decimal PackagingPrice, decimal TransactionFee, decimal TotalVatAmount, decimal Bonus, decimal AddedToAccount, decimal CouponDiscount, decimal TotalProductDiscountPrice, decimal TotalProductDiscount, decimal Total, CouponLine[] CouponLines, string Notes, string UnattendedNotes, string PlacementMessage, string DoorCode, int TimeslotDuration, int Id, string Email, int NumberOfProducts, int NumberOfPacks, int NumberOfDeposits) : Response(StatusCode), IOrderResponse; +internal record ShoppingListsResponse(int StatusCode, ShoppingList[] ShoppingListOverViewViewModels, int NumberOfPages) : Response(StatusCode), IShoppingListsResponse; +internal record ShoppingListResponse(int StatusCode, int Id, string Name, string Url, bool ContainsDeactivatedData, int ProductsCount, decimal TotalAmount, object[] ValidationFailures, Product[] Lines) : Response(StatusCode), IShoppingListResponse; +internal record CurrentBasketResponse(int StatusCode, string Id, Guid BasketGuid, Address InvoiceAddress, Address DeliveryAddress) : Response(StatusCode), ICurrentBasketResponse; \ No newline at end of file