mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2024-12-22 23:26:31 +01:00
909 lines
31 KiB
C#
909 lines
31 KiB
C#
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Serilog;
|
|
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
|
|
using TINK.Model.Device;
|
|
using TINK.Model.Logging;
|
|
using TINK.Repository.Exception;
|
|
using TINK.Repository.Request;
|
|
using TINK.Repository.Response;
|
|
|
|
namespace TINK.Repository
|
|
{
|
|
/// <summary> Object which manages calls to copri. </summary>
|
|
public class CopriCallsHttps : ICopriServer
|
|
{
|
|
/// <summary> Builds requests.</summary>
|
|
private IRequestBuilder requestBuilder;
|
|
|
|
/// <summary> Initializes a instance of the copri calls https object. </summary>
|
|
/// <param name="copriHost">Host to connect to. </param>
|
|
/// <param name="appContextInfo">Provides app related info (app name and version, merchantid) to pass to COPRI.</param>
|
|
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
|
|
/// <param name="sessionCookie">Session cookie if user is logged in, null otherwise.</param>
|
|
public CopriCallsHttps(
|
|
Uri copriHost,
|
|
AppContextInfo appContextInfo,
|
|
string uiIsoLangugageName,
|
|
string sessionCookie = null)
|
|
{
|
|
m_oCopriHost = copriHost
|
|
?? throw new System.Exception($"Can not construct {GetType()}- object. Uri of copri host must not be null.");
|
|
|
|
UserAgent = appContextInfo != null
|
|
? appContextInfo.UserAgent
|
|
: throw new System.Exception($"Can not construct {GetType()}- object. User agent must not be null or empty.");
|
|
|
|
requestBuilder = string.IsNullOrEmpty(sessionCookie)
|
|
? new RequestBuilder(appContextInfo.MerchantId, uiIsoLangugageName) as IRequestBuilder
|
|
: new RequestBuilderLoggedIn(appContextInfo.MerchantId, uiIsoLangugageName, sessionCookie);
|
|
}
|
|
|
|
/// <summary> Holds the URL for rest calls.</summary>
|
|
private Uri m_oCopriHost;
|
|
|
|
/// <summary> Spacifies name and version of app. </summary>
|
|
private string UserAgent { get; }
|
|
|
|
/// <summary> Returns true because value requested form copri server are returned. </summary>
|
|
public bool IsConnected => true;
|
|
|
|
/// <summary> Gets the merchant id.</summary>
|
|
public string MerchantId => requestBuilder.MerchantId;
|
|
|
|
/// <summary> Gets the session cookie if user is logged in, an empty string otherwise. </summary>
|
|
public string SessionCookie => requestBuilder.SessionCookie;
|
|
|
|
/// <summary> Logs user in. </summary>
|
|
/// <param name="mailAddress">Mailaddress of user to log in.</param>
|
|
/// <param name="password">Password to log in.</param>
|
|
/// <param name="deviceId">Id specifying user and hardware.</param>
|
|
/// <remarks>Response which holds auth cookie <see cref="ResponseBase.authcookie"/></remarks>
|
|
public async Task<AuthorizationResponse> DoAuthorizationAsync(
|
|
string mailAddress,
|
|
string password,
|
|
string deviceId)
|
|
=> await DoAuthorizationAsync(
|
|
m_oCopriHost.AbsoluteUri,
|
|
requestBuilder.DoAuthorization(mailAddress, password, deviceId),
|
|
() => requestBuilder.DoAuthorization(mailAddress, "********", deviceId),
|
|
UserAgent);
|
|
|
|
/// <summary> Logs user out. </summary>
|
|
/// <remarks>Response which holds auth cookie <see cref="ResponseBase.authcookie"/></remarks>
|
|
public async Task<AuthorizationoutResponse> DoAuthoutAsync()
|
|
=> await DoAuthoutAsync(m_oCopriHost.AbsoluteUri, requestBuilder.DoAuthout(), UserAgent);
|
|
|
|
/// <summary>Gets bikes available.</summary>
|
|
/// <returns>Response holding list of bikes.</returns>
|
|
public async Task<BikesAvailableResponse> GetBikesAvailableAsync()
|
|
=> await GetBikesAvailableAsync(m_oCopriHost.AbsoluteUri, requestBuilder.GetBikesAvailable(), UserAgent);
|
|
|
|
/// <summary> Gets a list of bikes reserved/ booked by acctive user. </summary>
|
|
/// <returns>Response holding list of bikes.</returns>
|
|
public async Task<BikesReservedOccupiedResponse> GetBikesOccupiedAsync()
|
|
{
|
|
try
|
|
{
|
|
return await GetBikesOccupiedAsync(m_oCopriHost.AbsoluteUri, requestBuilder.GetBikesOccupied(), UserAgent);
|
|
}
|
|
catch (NotSupportedException)
|
|
{
|
|
// No user logged in.
|
|
await Task.CompletedTask;
|
|
return ResponseHelper.GetBikesOccupiedNone();
|
|
}
|
|
}
|
|
|
|
/// <summary> Get list of stations. </summary>
|
|
/// <returns>List of files.</returns>
|
|
public async Task<StationsAvailableResponse> GetStationsAsync()
|
|
=> await GetStationsAsync(m_oCopriHost.AbsoluteUri, requestBuilder.GetStations(), UserAgent);
|
|
|
|
/// <summary> Get authentication keys. </summary>
|
|
/// <param name="bikeId">Id of the bike to get keys for.</param>
|
|
/// <returns>Response holding authentication keys.</returns>
|
|
public async Task<ReservationBookingResponse> GetAuthKeys(string bikeId)
|
|
=> await GetAuthKeysAsync(m_oCopriHost.AbsoluteUri, requestBuilder.CalculateAuthParameters(bikeId), UserAgent);
|
|
|
|
|
|
/// <summary> Gets booking request response.</summary>
|
|
/// <param name="bikeId">Id of the bike to book.</param>
|
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|
/// <returns>Booking response.</returns>
|
|
public async Task<ReservationBookingResponse> DoReserveAsync(
|
|
string bikeId,
|
|
Uri operatorUri)
|
|
=> await DoReserveAsync(
|
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|
requestBuilder.DoReserve(bikeId),
|
|
UserAgent);
|
|
|
|
/// <summary> Gets canel booking request response.</summary>
|
|
/// <param name="bikeId">Id of the bike to book.</param>
|
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|
/// <returns>Response on cancel booking request.</returns>
|
|
public async Task<ReservationCancelReturnResponse> DoCancelReservationAsync(
|
|
string bikeId,
|
|
Uri operatorUri)
|
|
=> await DoCancelReservationAsync(
|
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|
requestBuilder.DoCancelReservation(bikeId),
|
|
UserAgent);
|
|
|
|
/// <summary> Get authentication keys. </summary>
|
|
/// <param name="bikeId">Id of the bike to get keys for.</param>
|
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|
/// <returns>Response holding authentication keys.</returns>
|
|
public async Task<ReservationBookingResponse> CalculateAuthKeysAsync(
|
|
string bikeId,
|
|
Uri operatorUri)
|
|
=> await GetAuthKeysAsync(
|
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|
requestBuilder.CalculateAuthParameters(bikeId),
|
|
UserAgent);
|
|
|
|
/// <summary> Notifies COPRI about start of returning sequence. </summary>
|
|
/// <remarks> Operator specific call.</remarks>
|
|
/// <param name="bikeId">Id of the bike to return.</param>+
|
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|
/// <returns>Response on notification about start of returning sequence.</returns>
|
|
public async Task<ResponseBase> StartReturningBike(
|
|
string bikeId,
|
|
Uri operatorUri)
|
|
=> await DoStartReturningBike(
|
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|
requestBuilder.StartReturningBike(bikeId),
|
|
UserAgent);
|
|
|
|
/// <summary> Updates lock state for a booked bike. </summary>
|
|
/// <param name="bikeId">Id of the bike to update locking state for.</param>
|
|
/// <param name="location">Geolocation of lock.</param>
|
|
/// <param name="state">New locking state.</param>
|
|
/// <param name="batteryPercentage">Holds the filling level percentage of the battery.</param>
|
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|
/// <returns>Response on updating locking state.</returns>
|
|
public async Task<ReservationBookingResponse> UpdateLockingStateAsync(
|
|
string bikeId,
|
|
lock_state state,
|
|
Uri operatorUri,
|
|
LocationDto location,
|
|
double batteryLevel,
|
|
IVersionInfo versionInfo) =>
|
|
await DoUpdateLockingStateAsync(
|
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|
requestBuilder.UpateLockingState(bikeId, state, location, batteryLevel, versionInfo),
|
|
UserAgent);
|
|
|
|
/// <summary> Gets booking request request. </summary>
|
|
/// <param name="bikeId">Id of the bike to book.</param>
|
|
/// <param name="guid">Used to publish GUID from app to copri. Used for initial setup of bike in copri.</param>
|
|
/// <param name="batteryPercentage">Holds the filling level percentage of the battery.</param>
|
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|
/// <returns>Requst on booking request.</returns>
|
|
public async Task<ReservationBookingResponse> DoBookAsync(
|
|
string bikeId,
|
|
Guid guid,
|
|
double batteryPercentage,
|
|
Uri operatorUri)
|
|
=> await DoBookAsync(
|
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|
requestBuilder.DoBook(bikeId, guid, batteryPercentage),
|
|
UserAgent);
|
|
|
|
/// <summary> Books a bike and starts opening bike. </summary>
|
|
/// <param name="bikeId">Id of the bike to book.</param>
|
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|
/// <returns>Response on booking request.</returns>
|
|
public async Task<ReservationBookingResponse> BookAvailableAndStartOpeningAsync(
|
|
string bikeId,
|
|
Uri operatorUri)
|
|
=> await DoBookAsync(
|
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|
requestBuilder.BookAvailableAndStartOpening(bikeId),
|
|
UserAgent);
|
|
|
|
/// <summary> Books a bike and starts opening bike. </summary>
|
|
/// <param name="bikeId">Id of the bike to book.</param>
|
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|
/// <returns>Response on booking request.</returns>
|
|
public async Task<ReservationBookingResponse> BookReservedAndStartOpeningAsync(
|
|
string bikeId,
|
|
Uri operatorUri)
|
|
=> await DoBookAsync(
|
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|
requestBuilder.BookReservedAndStartOpening(bikeId),
|
|
UserAgent);
|
|
|
|
/// <summary> Returns a bike. </summary>
|
|
/// <param name="bikeId">Id of the bike to return.</param>
|
|
/// <param name="location">Geolocation of lock.</param>
|
|
/// <param name="smartDevice">Provides info about hard and software.</param>
|
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|
/// <returns>Response on returning request.</returns>
|
|
public async Task<DoReturnResponse> DoReturn(
|
|
string bikeId,
|
|
LocationDto location,
|
|
ISmartDevice smartDevice,
|
|
Uri operatorUri)
|
|
=> await DoReturn(
|
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|
requestBuilder.DoReturn(bikeId, location, smartDevice),
|
|
UserAgent);
|
|
|
|
/// <summary> Returns a bike and starts closing. </summary>
|
|
/// <param name="bikeId">Id of the bike to return.</param>
|
|
/// <param name="smartDevice">Provides info about hard and software.</param>
|
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|
/// <returns>Response on returning request.</returns>
|
|
public async Task<DoReturnResponse> ReturnAndStartClosingAsync(
|
|
string bikeId,
|
|
ISmartDevice smartDevice,
|
|
Uri operatorUri)
|
|
=> await DoReturn(
|
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|
requestBuilder.ReturnAndStartClosing(bikeId, smartDevice),
|
|
UserAgent);
|
|
|
|
/// <summary> Submits feedback to copri server. </summary>
|
|
/// <param name="bikeId">Id of the bike to which the feedback is related to.</param>
|
|
/// <param name="currentChargeBars">Null if bike has no engine or charge is unknown. Otherwise the charge filling level of the drive battery.</param>
|
|
/// <param name="isBikeBroken">True if bike is broken.</param>
|
|
/// <param name="message">General purpose message or error description.</param>
|
|
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
|
|
/// <returns>Response on submitting feedback request.</returns>
|
|
public async Task<SubmitFeedbackResponse> DoSubmitFeedback(
|
|
string bikeId,
|
|
int? currentChargeBars,
|
|
string message,
|
|
bool isBikeBroken,
|
|
Uri operatorUri) =>
|
|
await DoSubmitFeedback(
|
|
operatorUri?.AbsoluteUri ?? m_oCopriHost.AbsoluteUri,
|
|
requestBuilder.DoSubmitFeedback(bikeId, currentChargeBars, message, isBikeBroken),
|
|
UserAgent);
|
|
|
|
/// <summary> Submits mini survey to copri server. </summary>
|
|
/// <param name="answers">Collection of answers.</param>
|
|
public Task<ResponseBase> DoSubmitMiniSurvey(IDictionary<string, string> answers)
|
|
=> DoSubmitMiniSurvey(
|
|
m_oCopriHost.AbsoluteUri,
|
|
requestBuilder.DoSubmitMiniSurvey(answers),
|
|
UserAgent);
|
|
|
|
/// <summary> Logs user in. </summary>
|
|
/// <param name="copriHost">Host to connect to. </param>
|
|
/// <param name="command">Command to log user in.</param>
|
|
/// <remarks>Response which holds auth cookie <see cref="ResponseBase.authcookie"/></remarks>
|
|
public static async Task<AuthorizationResponse> DoAuthorizationAsync(
|
|
string copriHost,
|
|
string command,
|
|
Func<string> displayCommand,
|
|
string userAgent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
/// Extract session cookie from response.
|
|
string response = string.Empty;
|
|
try
|
|
{
|
|
response = await PostAsync(
|
|
copriHost,
|
|
command,
|
|
userAgent,
|
|
displayCommand); // Do not include password into exception output when an error occurres.
|
|
}
|
|
catch (System.Exception l_oException)
|
|
{
|
|
if (l_oException.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Login fehlgeschlagen aufgrund eines Netzwerkfehlers.", l_oException);
|
|
}
|
|
|
|
if (l_oException.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Login fehlgeschlagen aufgrund eines Netzwerkfehlers.", l_oException);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
return CopriCallsStatic.DeserializeResponse<AuthorizationResponse>(response, (version) => new UnsupportedCopriVersionDetectedException());
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
/// <summary> Logs user out. </summary>
|
|
/// <param name="copriHost">Host to connect to. </param>
|
|
/// <param name="command">Command to log user out.</param>
|
|
public static async Task<AuthorizationoutResponse> DoAuthoutAsync(
|
|
string p_strCopriHost,
|
|
string p_oCommand,
|
|
string userAgent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
string l_oLogoutResponse;
|
|
try
|
|
{
|
|
l_oLogoutResponse = await PostAsync(p_strCopriHost, p_oCommand, userAgent);
|
|
}
|
|
|
|
catch (System.Exception l_oException)
|
|
{
|
|
if (l_oException.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Login fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|
}
|
|
|
|
if (l_oException.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Login fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
/// Extract session cookie from response.
|
|
return CopriCallsStatic.DeserializeResponse<AuthorizationoutResponse>(l_oLogoutResponse, (version) => new UnsupportedCopriVersionDetectedException());
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get list of stations from file.
|
|
/// </summary>
|
|
/// <param name="p_strCopriHost">URL of the copri host to connect to.</param>
|
|
/// <param name="p_oCommand">Command to get stations.</param>
|
|
/// <returns>List of files.</returns>
|
|
public static async Task<StationsAvailableResponse> GetStationsAsync(
|
|
string p_strCopriHost,
|
|
string p_oCommand,
|
|
string userAgent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
string response;
|
|
try
|
|
{
|
|
response = await PostAsync(p_strCopriHost, p_oCommand, userAgent);
|
|
}
|
|
catch (System.Exception l_oException)
|
|
{
|
|
if (l_oException.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Abfage der verfügbaren Räder fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|
}
|
|
|
|
if (l_oException.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Abfage der verfügbaren Räder fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
// Extract bikes from response.
|
|
return CopriCallsStatic.DeserializeResponse(
|
|
response,
|
|
(version) => CopriCallsMonkeyStore.GetEmptyStationsAllResponse(version));
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
/// <summary> Gets a list of bikes from Copri. </summary>
|
|
/// <param name="copriHost">URL of the copri host to connect to.</param>
|
|
/// <param name="p_oCommand">Command to get bikes.</param>
|
|
/// <returns>Response holding list of bikes.</returns>
|
|
public static async Task<BikesAvailableResponse> GetBikesAvailableAsync(
|
|
string copriHost,
|
|
string command,
|
|
string userAgent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
string response;
|
|
try
|
|
{
|
|
response = await PostAsync(copriHost, command, userAgent);
|
|
}
|
|
catch (System.Exception l_oException)
|
|
{
|
|
if (l_oException.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Abfage der verfügbaren Räder fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|
}
|
|
|
|
if (l_oException.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Abfage der verfügbaren Räder fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
// Extract bikes from response.
|
|
return CopriCallsStatic.DeserializeResponse(
|
|
response,
|
|
(version) => CopriCallsMonkeyStore.GetEmptyBikesAvailableResponse(version));
|
|
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
/// <summary> Gets a list of bikes reserved/ booked by acctive user from Copri.</summary>
|
|
/// <param name="p_strCopriHost">URL of the copri host to connect to.</param>
|
|
/// <param name="p_oCommand">Command to post.</param>
|
|
/// <returns>Response holding list of bikes.</returns>
|
|
public static async Task<BikesReservedOccupiedResponse> GetBikesOccupiedAsync(
|
|
string p_strCopriHost,
|
|
string p_oCommand,
|
|
string userAgent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
string response;
|
|
try
|
|
{
|
|
response = await PostAsync(p_strCopriHost, p_oCommand, userAgent);
|
|
}
|
|
catch (System.Exception l_oException)
|
|
{
|
|
if (l_oException.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Abfage der reservierten/ gebuchten Räder fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|
}
|
|
|
|
if (l_oException.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Abfage der reservierten/ gebuchten Räder fehlgeschlagen wegen Netzwerkfehler.", l_oException);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
// Extract bikes from response.
|
|
return CopriCallsStatic.DeserializeResponse(
|
|
response,
|
|
(version) => CopriCallsMonkeyStore.GetEmptyBikesReservedOccupiedResponse(version));
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
/// <summary> Get auth keys from COPRI. </summary>
|
|
/// <param name="copriHost">Host to connect to. </param>
|
|
/// <param name="command">Command to log user in.</param>
|
|
/// <returns>Response on booking request.</returns>
|
|
public static async Task<ReservationBookingResponse> GetAuthKeysAsync(
|
|
string copriHost,
|
|
string command,
|
|
string userAgent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
string bikesAvaialbeResponse;
|
|
try
|
|
{
|
|
bikesAvaialbeResponse = await PostAsync(copriHost, command, userAgent);
|
|
}
|
|
catch (System.Exception exception)
|
|
{
|
|
if (exception.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Schlosssuche wegen Netzwerkfehler fehlgeschlagen.", exception);
|
|
}
|
|
|
|
if (exception.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Schlosssuche wegen Netzwerkfehler fehlgeschlagen.", exception);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
// Extract bikes from response.
|
|
return JsonConvertRethrow.DeserializeObject<ResponseContainer<ReservationBookingResponse>>(bikesAvaialbeResponse)?.shareejson;
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
/// <summary> Gets booking request response. </summary>
|
|
/// <param name="copriHost">Host to connect to. </param>
|
|
/// <param name="command">Command to log user in.</param>
|
|
/// <returns>Response on booking request.</returns>
|
|
public static async Task<ReservationBookingResponse> DoReserveAsync(
|
|
string copriHost,
|
|
string command,
|
|
string userAgent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
string bikesAvaialbeResponse;
|
|
try
|
|
{
|
|
bikesAvaialbeResponse = await PostAsync(copriHost, command, userAgent);
|
|
}
|
|
catch (System.Exception exception)
|
|
{
|
|
if (exception.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Reservierung des Fahrrads wegen Netzwerkfehler fehlgeschlagen.", exception);
|
|
}
|
|
|
|
if (exception.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Reservierung des Fahrrads wegen Netzwerkfehler fehlgeschlagen.", exception);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
// Extract bikes from response.
|
|
return JsonConvertRethrow.DeserializeObject<ResponseContainer<ReservationBookingResponse>>(bikesAvaialbeResponse)?.shareejson;
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
/// <summary> Gets canel booking request response.</summary>
|
|
/// <param name="copriHost">Host to connect to. </param>
|
|
/// <param name="command">Command to log user in.</param>
|
|
/// <returns>Response on cancel booking request.</returns>
|
|
public static async Task<ReservationCancelReturnResponse> DoCancelReservationAsync(
|
|
string copriHost,
|
|
string command,
|
|
string userAgent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
string l_oBikesAvaialbeResponse;
|
|
try
|
|
{
|
|
l_oBikesAvaialbeResponse = await PostAsync(copriHost, command, userAgent);
|
|
}
|
|
catch (System.Exception l_oException)
|
|
{
|
|
if (l_oException.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Reservierung des Fahrrads aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|
}
|
|
|
|
if (l_oException.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Reservierung des Fahrrads aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
// Extract bikes from response.
|
|
return JsonConvertRethrow.DeserializeObject<ResponseContainer<ReservationCancelReturnResponse>>(l_oBikesAvaialbeResponse)?.shareejson;
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
public static async Task<ResponseBase> DoStartReturningBike(
|
|
string copriHost,
|
|
string command,
|
|
string agent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
string response;
|
|
try
|
|
{
|
|
response = await PostAsync(copriHost, command, agent);
|
|
}
|
|
catch (System.Exception exception)
|
|
{
|
|
if (exception.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Benachrichtigung von Start der Rückgabe wegen Netzwerkfehler fehlgeschlagen.", exception);
|
|
}
|
|
|
|
if (exception.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Benachrichtigung von Start der Rückgabe wegen Netzwerkfehler fehlgeschlagen.", exception);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
// Extract bikes from response.
|
|
return JsonConvertRethrow.DeserializeObject<ResponseContainer<ResponseBase>>(response)?.shareejson;
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
public static async Task<ReservationBookingResponse> DoUpdateLockingStateAsync(
|
|
string copriHost,
|
|
string command,
|
|
string agent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
string bikesAvaialbeResponse;
|
|
try
|
|
{
|
|
bikesAvaialbeResponse = await PostAsync(copriHost, command, agent);
|
|
}
|
|
catch (System.Exception exception)
|
|
{
|
|
if (exception.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Aktualisierung des Schlossstatuses wegen Netzwerkfehler fehlgeschlagen.", exception);
|
|
}
|
|
|
|
if (exception.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Aktualisierung des Schlossstatuses wegen Netzwerkfehler fehlgeschlagen.", exception);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
// Extract bikes from response.
|
|
return JsonConvertRethrow.DeserializeObject<ResponseContainer<ReservationBookingResponse>>(bikesAvaialbeResponse)?.shareejson;
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
public static async Task<ReservationBookingResponse> DoBookAsync(
|
|
string copriHost,
|
|
string command,
|
|
string agent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
string bikesAvaialbeResponse;
|
|
try
|
|
{
|
|
bikesAvaialbeResponse = await PostAsync(copriHost, command, agent);
|
|
}
|
|
catch (System.Exception exception)
|
|
{
|
|
if (exception.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Buchung des Fahrrads wegen Netzwerkfehler fehlgeschlagen.", exception);
|
|
}
|
|
|
|
if (exception.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Buchung des Fahrrads wegen Netzwerkfehler fehlgeschlagen.", exception);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
// Extract bikes from response.
|
|
return JsonConvertRethrow.DeserializeObject<ResponseContainer<ReservationBookingResponse>>(bikesAvaialbeResponse)?.shareejson;
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
public static async Task<DoReturnResponse> DoReturn(
|
|
string copriHost,
|
|
string command,
|
|
string userAgent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
string doReturnResponse;
|
|
try
|
|
{
|
|
doReturnResponse = await PostAsync(copriHost, command, userAgent);
|
|
}
|
|
catch (System.Exception l_oException)
|
|
{
|
|
if (l_oException.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Rückgabe des Fahrrads aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|
}
|
|
|
|
if (l_oException.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Rückgabe des Fahrrads aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
// Extract bikes from response.
|
|
return JsonConvertRethrow.DeserializeObject<ResponseContainer<DoReturnResponse>>(doReturnResponse)?.shareejson;
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
public async Task<SubmitFeedbackResponse> DoSubmitFeedback(
|
|
string copriHost,
|
|
string command,
|
|
string userAgent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
string userFeedbackResponse;
|
|
try
|
|
{
|
|
userFeedbackResponse = await PostAsync(copriHost, command, userAgent);
|
|
}
|
|
catch (System.Exception l_oException)
|
|
{
|
|
if (l_oException.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Senden der Rückmeldung aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|
}
|
|
|
|
if (l_oException.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Senden der Rückmeldung aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
// Extract bikes from response.
|
|
return JsonConvertRethrow.DeserializeObject<ResponseContainer<SubmitFeedbackResponse>>(userFeedbackResponse)?.shareejson;
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
/// <summary> Submits mini survey to copri server. </summary>
|
|
public async Task<ResponseBase> DoSubmitMiniSurvey(
|
|
string copriHost,
|
|
string command,
|
|
string userAgent = null)
|
|
{
|
|
#if !WINDOWS_UWP
|
|
string miniSurveyResponse;
|
|
try
|
|
{
|
|
miniSurveyResponse = await PostAsync(copriHost, command, userAgent);
|
|
}
|
|
catch (System.Exception l_oException)
|
|
{
|
|
if (l_oException.GetIsConnectFailureException())
|
|
{
|
|
throw new WebConnectFailureException("Senden der Miniumfrage aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|
}
|
|
|
|
if (l_oException.GetIsForbiddenException())
|
|
{
|
|
throw new WebForbiddenException("Senden der der Miniumfrage aufgrund eines Netzwerkfehlers fehlgeschlagen.", l_oException);
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
// Extract bikes from response.
|
|
return JsonConvertRethrow.DeserializeObject<ResponseContainer<ResponseBase>>(miniSurveyResponse)?.shareejson;
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
/// <summary> http get- request.</summary>
|
|
/// <param name="Url">Ulr to get info from.</param>
|
|
/// <returns>response from server</returns>
|
|
public static async Task<string> Get(string Url)
|
|
{
|
|
string result = string.Empty;
|
|
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(Url);
|
|
myRequest.Method = "GET";
|
|
using (var myResponse = await myRequest.GetResponseAsync())
|
|
{
|
|
using (var sr = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8))
|
|
{
|
|
result = sr.ReadToEnd();
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary> http- post request.</summary>
|
|
/// <param name="command">Command to send.</param>
|
|
/// <param name="displayCommand">Command to display/ log used for error handling.</param>
|
|
/// <param name="uRL">Address of server to communicate with.</param>
|
|
/// <returns>Response as text.</returns>
|
|
/// <changelog> An unused member PostAsyncHttpClient using HttpClient for posting was removed 2020-04-02.</changelog>
|
|
private static async Task<string> PostAsync(
|
|
string uRL,
|
|
string command,
|
|
string userAgent = null,
|
|
Func<string> displayCommand = null)
|
|
{
|
|
if (string.IsNullOrEmpty(command))
|
|
{
|
|
Log.ForContext<CopriCallsHttps>().Fatal("Can not post command. Command must not be null or empty.");
|
|
|
|
throw new ArgumentException("Can not post command. Command must not be null or empty.");
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(uRL))
|
|
{
|
|
Log.ForContext<CopriCallsHttps>().Fatal("Can not post command. Host must not be null or empty.");
|
|
|
|
throw new ArgumentException("Can not post command. Host must not be null or empty.");
|
|
}
|
|
|
|
// Get display version of command to used for display/ logging (password should never be included in output)
|
|
Func<string> displayCommandFunc = displayCommand ?? delegate () { return command; };
|
|
|
|
try
|
|
{
|
|
#if !WINDOWS_UWP
|
|
var l_strHost = uRL;
|
|
|
|
// Returns a http request.
|
|
var request = WebRequest.CreateHttp(l_strHost);
|
|
|
|
request.Method = "POST";
|
|
request.ContentType = "application/x-www-form-urlencoded";
|
|
request.UserAgent = userAgent;
|
|
|
|
// Workaround for issue https://bugzilla.xamarin.com/show_bug.cgi?id=57705
|
|
// If not KeepAlive is set to true Stream.Write leads arbitrarily to an object disposed exception.
|
|
request.KeepAlive = true;
|
|
|
|
byte[] postData = Encoding.UTF8.GetBytes(command);
|
|
|
|
request.ContentLength = postData.Length;
|
|
|
|
// Get the request stream.
|
|
using (Stream dataStream = await request.GetRequestStreamAsync())
|
|
{
|
|
// Write the data to the request stream.
|
|
await dataStream.WriteAsync(postData, 0, postData.Length);
|
|
}
|
|
|
|
// Get the response.
|
|
var webResponse = await request.GetResponseAsync() as HttpWebResponse;
|
|
|
|
if (webResponse == null)
|
|
{
|
|
throw new System.Exception(string.Format("Reserve request failed. Response form from server was not of expected type."));
|
|
}
|
|
|
|
if (webResponse.StatusCode != HttpStatusCode.OK)
|
|
{
|
|
throw new CommunicationException(string.Format(
|
|
"Posting request {0} failed. Expected status code is {1} but was {2}.",
|
|
displayCommandFunc(),
|
|
HttpStatusCode.OK,
|
|
webResponse.StatusCode));
|
|
}
|
|
|
|
string response = string.Empty;
|
|
|
|
// Get the request stream.
|
|
using (Stream l_oDataStream = webResponse.GetResponseStream())
|
|
using (StreamReader l_oReader = new StreamReader(l_oDataStream))
|
|
{
|
|
// Read the content.
|
|
response = l_oReader.ReadToEnd();
|
|
|
|
// Display the content.
|
|
Console.WriteLine(response);
|
|
|
|
// Clean up the streams.
|
|
webResponse.Close();
|
|
}
|
|
|
|
Log.ForContext<CopriCallsHttps>().Verbose("Post command {DisplayCommand} to host {URL} received {ResponseText:j}.", displayCommandFunc(), uRL, response);
|
|
|
|
return response;
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
catch (System.Exception exception)
|
|
{
|
|
Log.ForContext<CopriCallsHttps>().InformationOrError("Posting command {DisplayCommand} to host {URL} failed. {Exception}.", displayCommandFunc(), uRL, exception);
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
}
|