-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
162 additions
and
189 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<ILoginResponse> LoginAsync(string userName, string password); | ||
Task<ILoginResponse> LoginAsync(string userName, string password); | ||
|
||
Task<ICurrentUserResponse> GetCurrentUserAsync(); | ||
Task<ICurrentUserResponse> GetCurrentUserAsync(); | ||
|
||
Task<IOrderHistoryResponse> GetOrderHistoryAsync(int skip, int take); | ||
Task<IOrderHistoryResponse> GetOrderHistoryAsync(int skip, int take); | ||
|
||
Task<IOrderResponse> GetOrderAsync(int orderId); | ||
Task<IOrderResponse> GetOrderAsync(int orderId); | ||
|
||
Task<IShoppingListsResponse> GetShoppingListsAsync(int skip, int take); | ||
Task<IShoppingListsResponse> GetShoppingListsAsync(int skip, int take); | ||
|
||
Task<IShoppingListResponse> GetShoppingListAsync(int shoppingListId); | ||
Task<IShoppingListResponse> GetShoppingListAsync(int shoppingListId); | ||
|
||
Task<ICurrentBasketResponse> GetCurrentBasketAsync(); | ||
} | ||
Task<ICurrentBasketResponse> GetCurrentBasketAsync(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<ILoginResponse> 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<LoginResponse>(jsonString); | ||
public async Task<ILoginResponse> 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<LoginResponse>(jsonString); | ||
|
||
_cookieJar = jar; | ||
_cookieJar = jar; | ||
|
||
return deserialized with { StatusCode = response.StatusCode }; | ||
} | ||
return deserialized with { StatusCode = response.StatusCode }; | ||
} | ||
|
||
public async Task<ICurrentUserResponse> GetCurrentUserAsync() | ||
{ | ||
return await DoFlurlGet<CurrentUserResponse, ICurrentUserResponse>(new string[] { "webapi", "user", "GetCurrentUser" }).ConfigureAwait(false); | ||
} | ||
public async Task<ICurrentUserResponse> GetCurrentUserAsync() => await DoFlurlGet<CurrentUserResponse, ICurrentUserResponse>(["webapi", "user", "GetCurrentUser"]).ConfigureAwait(false); | ||
|
||
public async Task<IOrderHistoryResponse> GetOrderHistoryAsync(int skip, int take) | ||
{ | ||
return await DoFlurlGet<OrderHistoryResponse, IOrderHistoryResponse>(new string[] { "webapi", "order", "GetBasicOrderHistory" }, new { skip, take }); | ||
} | ||
public async Task<IOrderHistoryResponse> GetOrderHistoryAsync(int skip, int take) | ||
{ | ||
return await DoFlurlGet<OrderHistoryResponse, IOrderHistoryResponse>(["webapi", "order", "GetBasicOrderHistory"], new { skip, take }); | ||
} | ||
|
||
public async Task<IOrderResponse> GetOrderAsync(int orderId) | ||
{ | ||
return await DoFlurlGet<OrderResponse, IOrderResponse>(new string[] { "webapi", "order", "GetOrderHistory" }, new { orderNumber = orderId }); | ||
} | ||
public async Task<IOrderResponse> GetOrderAsync(int orderId) => await DoFlurlGet<OrderResponse, IOrderResponse>(["webapi", "order", "GetOrderHistory"], new { orderNumber = orderId }); | ||
|
||
public async Task<IShoppingListsResponse> GetShoppingListsAsync(int skip, int take) | ||
{ | ||
return await DoFlurlGet<ShoppingListsResponse, IShoppingListsResponse>(new string[] { "webapi", "ShoppingList", "GetShoppingLists" }, new { skip, take }); | ||
} | ||
public async Task<IShoppingListsResponse> GetShoppingListsAsync(int skip, int take) => await DoFlurlGet<ShoppingListsResponse, IShoppingListsResponse>(["webapi", "ShoppingList", "GetShoppingLists"], new { skip, take }); | ||
|
||
public async Task<IShoppingListResponse> GetShoppingListAsync(int shoppingListId) | ||
{ | ||
return await DoFlurlGet<ShoppingListResponse, IShoppingListResponse>(new string[] { "webapi", "ShoppingList", "GetShoppingList" }, new { listId = shoppingListId }); | ||
} | ||
public async Task<IShoppingListResponse> GetShoppingListAsync(int shoppingListId) => await DoFlurlGet<ShoppingListResponse, IShoppingListResponse>(["webapi", "ShoppingList", "GetShoppingList"], new { listId = shoppingListId }); | ||
|
||
public async Task<ICurrentBasketResponse> GetCurrentBasketAsync() | ||
{ | ||
return await DoFlurlGet<CurrentBasketResponse, ICurrentBasketResponse>(new string[] { "webapi", "basket", "GetBasket" }); | ||
} | ||
public async Task<ICurrentBasketResponse> GetCurrentBasketAsync() => await DoFlurlGet<CurrentBasketResponse, ICurrentBasketResponse>(["webapi", "basket", "GetBasket"]); | ||
|
||
private async Task<TResponseInterface> DoFlurlGet<TResponseImplementation, TResponseInterface>(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<TResponseImplementation>(jsonString); | ||
private async Task<TResponseInterface> DoFlurlGet<TResponseImplementation, TResponseInterface>(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<TResponseImplementation>(jsonString); | ||
|
||
return deserialized with { StatusCode = response.StatusCode }; | ||
} | ||
} | ||
return deserialized with { StatusCode = response.StatusCode }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
namespace NemligSharp; | ||
|
||
internal record LoginPayload(string Username, string Password, bool AutoLogin = false, bool CheckForExistingProducts = true, bool DoMerge = true, bool AppInstalled = false); |
Oops, something went wrong.