mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-06-22 05:47:28 +02:00
Code updated to 3.0.238
This commit is contained in:
parent
3302d80678
commit
9c6a1fa92b
257 changed files with 7763 additions and 2861 deletions
|
@ -1,10 +1,11 @@
|
|||
using Serilog;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Repository;
|
||||
using TINK.Model.Repository.Request;
|
||||
using TINK.Model.Repository.Response;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Request;
|
||||
using TINK.Repository.Response;
|
||||
using TINK.Model.User.Account;
|
||||
using TINK.Model.Device;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
@ -122,7 +123,8 @@ namespace TINK.Model.Connector
|
|||
|
||||
public async Task DoReturn(
|
||||
Bikes.Bike.BluetoothLock.IBikeInfoMutable bike,
|
||||
LocationDto location)
|
||||
LocationDto location,
|
||||
ISmartDevice smartDevice)
|
||||
{
|
||||
Log.ForContext<Command>().Error("Unexpected returning request detected. No user logged in.");
|
||||
await Task.CompletedTask;
|
||||
|
@ -132,7 +134,11 @@ namespace TINK.Model.Connector
|
|||
/// Submits feedback to copri server.
|
||||
/// </summary>
|
||||
/// <param name="userFeedback">Feedback to submit.</param>
|
||||
#if USCSHARP9
|
||||
public async Task DoSubmitFeedback(ICommand.IUserFeedback userFeedback, Uri opertorUri)
|
||||
#else
|
||||
public async Task DoSubmitFeedback(IUserFeedback userFeedback, Uri opertorUri)
|
||||
#endif
|
||||
{
|
||||
Log.ForContext<Command>().Error("Unexpected submit feedback request detected. No user logged in.");
|
||||
await Task.CompletedTask;
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
using TINK.Model.Repository;
|
||||
using TINK.Model.Repository.Exception;
|
||||
using TINK.Model.Repository.Request;
|
||||
using TINK.Model.Repository.Response;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Request;
|
||||
using TINK.Repository.Response;
|
||||
using TINK.Model.User.Account;
|
||||
using TINK.Model.Device;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
@ -30,7 +31,7 @@ namespace TINK.Model.Connector
|
|||
/// Logs user in.
|
||||
/// If log in succeeds either and session might be updated if it was no more valid (logged in by an different device).
|
||||
/// If log in fails (password modified) session cookie is set to empty.
|
||||
/// If communication fails an TINK.Model.Repository.Exception is thrown.
|
||||
/// If communication fails an TINK.Repository.Exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="p_oAccount">Account to use for login.</param>
|
||||
public Task<IAccount> DoLogin(string p_strMail, string p_strPassword, string p_strDeviceId)
|
||||
|
@ -242,12 +243,13 @@ namespace TINK.Model.Connector
|
|||
}
|
||||
|
||||
/// <summary> Request to return a bike.</summary>
|
||||
/// <param name="latitude">Latitude of the bike.</param>
|
||||
/// <param name="longitude">Longitude of the bike.</param>
|
||||
/// <param name="bike">Bike to return.</param>
|
||||
/// <param name="locaton">Position of the bike.</param>
|
||||
/// <param name="smartDevice">Provides info about hard and software.</param>
|
||||
public async Task DoReturn(
|
||||
Bikes.Bike.BluetoothLock.IBikeInfoMutable bike,
|
||||
LocationDto location)
|
||||
LocationDto location,
|
||||
ISmartDevice smartDevice)
|
||||
{
|
||||
if (bike == null)
|
||||
{
|
||||
|
@ -257,7 +259,7 @@ namespace TINK.Model.Connector
|
|||
ReservationCancelReturnResponse l_oResponse;
|
||||
try
|
||||
{
|
||||
l_oResponse = (await CopriServer.DoReturn(bike.Id, location, bike.OperatorUri)).GetIsReturnBikeResponseOk(bike.Id);
|
||||
l_oResponse = (await CopriServer.DoReturn(bike.Id, location, smartDevice, bike.OperatorUri)).GetIsReturnBikeResponseOk(bike.Id);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -272,8 +274,12 @@ namespace TINK.Model.Connector
|
|||
/// Submits feedback to copri server.
|
||||
/// </summary>
|
||||
/// <param name="userFeedback">Feedback to submit.</param>
|
||||
#if USCSHARP9
|
||||
public async Task DoSubmitFeedback(ICommand.IUserFeedback userFeedback, Uri opertorUri)
|
||||
=> await CopriServer.DoSubmitFeedback(userFeedback.Message, userFeedback.IsBikeBroken, opertorUri);
|
||||
|
||||
=> await CopriServer.DoSubmitFeedback(userFeedback.BikeId, userFeedback.Message, userFeedback.IsBikeBroken, opertorUri);
|
||||
#else
|
||||
public async Task DoSubmitFeedback(IUserFeedback userFeedback, Uri opertorUri)
|
||||
=> await CopriServer.DoSubmitFeedback(userFeedback.BikeId, userFeedback.Message, userFeedback.IsBikeBroken, opertorUri);
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Repository.Request;
|
||||
using TINK.Repository.Request;
|
||||
using TINK.Model.User.Account;
|
||||
using TINK.Model.Device;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
@ -44,9 +45,10 @@ namespace TINK.Model.Connector
|
|||
Task DoBook(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike);
|
||||
|
||||
/// <summary> Request to return a bike.</summary>
|
||||
/// <param name="location">Geolocation of lock when returning bike.</param>
|
||||
/// <param name="bike">Bike to return.</param>
|
||||
Task DoReturn(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike, LocationDto geolocation = null);
|
||||
/// <param name="location">Geolocation of lock when returning bike.</param>
|
||||
/// <param name="smartDevice">Provides info about hard and software.</param>
|
||||
Task DoReturn(Bikes.Bike.BluetoothLock.IBikeInfoMutable bike, LocationDto geolocation = null, ISmartDevice smartDevice = null);
|
||||
|
||||
/// <summary> True if connector has access to copri server, false if cached values are used. </summary>
|
||||
bool IsConnected { get; }
|
||||
|
@ -55,12 +57,15 @@ namespace TINK.Model.Connector
|
|||
string SessionCookie { get; }
|
||||
|
||||
Task DoSubmitFeedback(IUserFeedback userFeedback, Uri opertorUri);
|
||||
|
||||
#if USCSHARP9
|
||||
/// <summary>
|
||||
/// Feedback given by user when returning bike.
|
||||
/// </summary>
|
||||
public interface IUserFeedback
|
||||
{
|
||||
/// <summary> Id of the bike to which the feedback is related to.</summary>
|
||||
string BikeId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds whether bike is broken or not.
|
||||
/// </summary>
|
||||
|
@ -74,12 +79,37 @@ namespace TINK.Model.Connector
|
|||
/// </summary>
|
||||
string Message { get; }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>Defines delegate to be raised whenever login state changes.</summary>
|
||||
/// <param name="p_oEventArgs">Holds session cookie and mail address if user logged in successfully.</param>
|
||||
public delegate void LoginStateChangedEventHandler(object p_oSender, LoginStateChangedEventArgs p_oEventArgs);
|
||||
|
||||
#if !USCSHARP9
|
||||
/// <summary>
|
||||
/// Feedback given by user when returning bike.
|
||||
/// </summary>
|
||||
public interface IUserFeedback
|
||||
{
|
||||
/// <summary> Id of the bike to which the feedback is related to.</summary>
|
||||
string BikeId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds whether bike is broken or not.
|
||||
/// </summary>
|
||||
bool IsBikeBroken { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds either
|
||||
/// - general feedback
|
||||
/// - error description of broken bike
|
||||
/// or both.
|
||||
/// </summary>
|
||||
string Message { get; }
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary> Event arguments to notify about changes of logged in state.</summary>
|
||||
public class LoginStateChangedEventArgs : EventArgs
|
||||
{
|
||||
|
|
|
@ -1,9 +1,25 @@
|
|||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
#if USCSHARP9
|
||||
public record UserFeedbackDto : ICommand.IUserFeedback
|
||||
{
|
||||
public string BikeId { get; init; }
|
||||
public bool IsBikeBroken { get; init; }
|
||||
public string Message { get; init; }
|
||||
}
|
||||
#else
|
||||
#if USCSHARP9
|
||||
public class UserFeedbackDto : ICommand.IUserFeedback
|
||||
#else
|
||||
public class UserFeedbackDto : IUserFeedback
|
||||
#endif
|
||||
{
|
||||
public string BikeId { get; set; }
|
||||
|
||||
public bool IsBikeBroken { get; set; }
|
||||
|
||||
public string Message { get; set; }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Model.Repository;
|
||||
using TINK.Repository;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Model.Repository;
|
||||
using TINK.Repository;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
|
|
@ -1,13 +1,26 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace TINK.Model.Connector.Filter
|
||||
{
|
||||
public static class GroupFilterFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates filter object.
|
||||
/// </summary>
|
||||
/// <param name="group">if value consists
|
||||
/// - list of strings entries are used to filter (intersect) with or if value is
|
||||
/// - null or an empty list null filter is applied, i.e. filtering is off.</param>
|
||||
/// <returns>Filtering object.</returns>
|
||||
/// <remarks>
|
||||
/// Tread group values of null and empty lists as marker to turn filtering off to handle COPRI responses maximal flexible.
|
||||
/// </remarks>
|
||||
public static IGroupFilter Create(IEnumerable<string> group)
|
||||
{
|
||||
return group != null ? (IGroupFilter) new IntersectGroupFilter(group) : new NullGroupFilter();
|
||||
return group != null && group.Count() > 0
|
||||
? (IGroupFilter) new IntersectGroupFilter(group) :
|
||||
new NullGroupFilter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,29 +86,33 @@ namespace TINK.Model.Connector
|
|||
/// <returns></returns>
|
||||
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
|
||||
{
|
||||
var result = await m_oInnerQuery.GetBikesAndStationsAsync();
|
||||
// Bikes and stations from COPRI or cache
|
||||
var providerBikesAndStations = await m_oInnerQuery.GetBikesAndStationsAsync();
|
||||
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
result.Source,
|
||||
new StationsAndBikesContainer(
|
||||
new StationDictionary(result.Response.StationsAll.CopriVersion, DoFilter(result.Response.StationsAll, Filter)),
|
||||
new BikeCollection(DoFilter(result.Response.Bikes, Filter))),
|
||||
result.Exception);
|
||||
// Do filtering.
|
||||
var filteredStationsDictionary = new StationDictionary(providerBikesAndStations.Response.StationsAll.CopriVersion, DoFilter(providerBikesAndStations.Response.StationsAll, Filter));
|
||||
var filteredBikesDictionary = new BikeCollection(DoFilter(providerBikesAndStations.Response.Bikes, Filter));
|
||||
var filteredBikesAndStations = new Result<StationsAndBikesContainer>(
|
||||
providerBikesAndStations.Source,
|
||||
new StationsAndBikesContainer(filteredStationsDictionary, filteredBikesDictionary),
|
||||
providerBikesAndStations.Exception); ;
|
||||
|
||||
return filteredBikesAndStations;
|
||||
}
|
||||
|
||||
/// <summary> Filter bikes by group. </summary>
|
||||
/// <param name="p_oBikes">Bikes to filter.</param>
|
||||
/// <param name="bikes">Bikes to filter.</param>
|
||||
/// <returns>Filtered bikes.</returns>
|
||||
private static Dictionary<int, BikeInfo> DoFilter(BikeCollection p_oBikes, IGroupFilter filter)
|
||||
private static Dictionary<string, BikeInfo> DoFilter(BikeCollection bikes, IGroupFilter filter)
|
||||
{
|
||||
return p_oBikes.Where(x => filter.DoFilter(x.Group).Count() > 0).ToDictionary(x => x.Id);
|
||||
return bikes.Where(x => filter.DoFilter(x.Group).Count() > 0).ToDictionary(x => x.Id);
|
||||
}
|
||||
|
||||
/// <summary> Filter stations by broup. </summary>
|
||||
/// <returns></returns>
|
||||
private static Dictionary<int, Station.Station> DoFilter(StationDictionary p_oStations, IGroupFilter filter)
|
||||
private static Dictionary<string, IStation> DoFilter(StationDictionary stations, IGroupFilter filter)
|
||||
{
|
||||
return p_oStations.Where(x => filter.DoFilter(x.Group).Count() > 0).ToDictionary((x => x.Id));
|
||||
return stations.Where(x => filter.DoFilter(x.Group).Count() > 0).ToDictionary(x => x.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,18 +90,18 @@ namespace TINK.Model.Connector
|
|||
}
|
||||
|
||||
/// <summary> Filter bikes by group. </summary>
|
||||
/// <param name="p_oBikes">Bikes to filter.</param>
|
||||
/// <param name="bikes">Bikes to filter.</param>
|
||||
/// <returns>Filtered bikes.</returns>
|
||||
public static Dictionary<int, BikeInfo> DoFilter(BikeCollection p_oBikes, IEnumerable<string> p_oFilter)
|
||||
public static Dictionary<string, BikeInfo> DoFilter(BikeCollection bikes, IEnumerable<string> filter)
|
||||
{
|
||||
return p_oBikes.Where(x => x.Group.Intersect(p_oFilter).Count() > 0).ToDictionary(x => x.Id);
|
||||
return bikes.Where(x => x.Group.Intersect(filter).Count() > 0).ToDictionary(x => x.Id);
|
||||
}
|
||||
|
||||
/// <summary> Filter stations by broup. </summary>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<int, Station.Station> DoFilter(StationDictionary p_oStations, IEnumerable<string> p_oFilter)
|
||||
public static Dictionary<string, IStation> DoFilter(StationDictionary stations, IEnumerable<string> p_oFilter)
|
||||
{
|
||||
return p_oStations.Where(x => x.Group.Intersect(p_oFilter).Count() > 0).ToDictionary((x => x.Id));
|
||||
return stations.Where(x => x.Group.Intersect(p_oFilter).Count() > 0).ToDictionary(x => x.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using TINK.Model.Repository;
|
||||
using TINK.Repository;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using TINK.Model.Repository;
|
||||
using TINK.Repository;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Collections.Generic;
|
|||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Model.Repository;
|
||||
using TINK.Repository;
|
||||
using BikeInfo = TINK.Model.Bike.BC.BikeInfo;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
|
@ -70,7 +70,7 @@ namespace TINK.Model.Connector
|
|||
Log.ForContext<CachedQuery>().Error("Unexpected call to get be bikes occpied detected. No user is logged in.");
|
||||
return new Result<BikeCollection>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
await Task.Run(() => new BikeCollection(new Dictionary<int, BikeInfo>())),
|
||||
await Task.Run(() => new BikeCollection(new Dictionary<string, BikeInfo>())),
|
||||
new System.Exception("Abfrage der reservierten/ gebuchten Räder nicht möglich. Kein Benutzer angemeldet."));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
using MonkeyCache.FileStore;
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Model.Repository;
|
||||
using TINK.Repository;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
@ -31,73 +30,74 @@ namespace TINK.Model.Connector
|
|||
/// <summary> Gets all stations including postions.</summary>
|
||||
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
|
||||
{
|
||||
var resultStations = await server.GetStations();
|
||||
var stationsResponse = await server.GetStations();
|
||||
|
||||
if (resultStations.Source == typeof(CopriCallsMonkeyStore)
|
||||
|| resultStations.Exception != null)
|
||||
if (stationsResponse.Source == typeof(CopriCallsMonkeyStore)
|
||||
|| stationsResponse.Exception != null)
|
||||
{
|
||||
// Stations were read from cache ==> get bikes availbalbe and occupied from cache as well to avoid inconsistencies
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
resultStations.Source,
|
||||
stationsResponse.Source,
|
||||
new StationsAndBikesContainer(
|
||||
resultStations.Response.GetStationsAllMutable(),
|
||||
stationsResponse.Response.GetStationsAllMutable(),
|
||||
UpdaterJSON.GetBikesAll(
|
||||
(await server.GetBikesAvailable(true)).Response,
|
||||
(await server.GetBikesOccupied(true)).Response,
|
||||
Mail,
|
||||
DateTimeProvider)),
|
||||
resultStations.Exception);
|
||||
stationsResponse.Exception);
|
||||
}
|
||||
|
||||
var l_oBikesAvailableResponse = await server.GetBikesAvailable();
|
||||
if (l_oBikesAvailableResponse.Source == typeof(CopriCallsMonkeyStore)
|
||||
|| l_oBikesAvailableResponse.Exception != null)
|
||||
var bikesAvailableResponse = await server.GetBikesAvailable();
|
||||
if (bikesAvailableResponse.Source == typeof(CopriCallsMonkeyStore)
|
||||
|| bikesAvailableResponse.Exception != null)
|
||||
{
|
||||
// Bikes avilable were read from cache ==> get bikes occupied from cache as well to avoid inconsistencies
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
l_oBikesAvailableResponse.Source,
|
||||
bikesAvailableResponse.Source,
|
||||
new StationsAndBikesContainer(
|
||||
(await server.GetStations(true)).Response.GetStationsAllMutable(),
|
||||
UpdaterJSON.GetBikesAll(l_oBikesAvailableResponse.Response,
|
||||
UpdaterJSON.GetBikesAll(bikesAvailableResponse.Response,
|
||||
(await server.GetBikesOccupied(true)).Response,
|
||||
Mail,
|
||||
DateTimeProvider)),
|
||||
l_oBikesAvailableResponse.Exception);
|
||||
bikesAvailableResponse.Exception);
|
||||
}
|
||||
|
||||
var l_oBikesOccupiedResponse = await server.GetBikesOccupied();
|
||||
if (l_oBikesOccupiedResponse.Source == typeof(CopriCallsMonkeyStore)
|
||||
|| l_oBikesOccupiedResponse.Exception != null)
|
||||
var bikesOccupiedResponse = await server.GetBikesOccupied();
|
||||
if (bikesOccupiedResponse.Source == typeof(CopriCallsMonkeyStore)
|
||||
|| bikesOccupiedResponse.Exception != null)
|
||||
{
|
||||
// Bikes occupied were read from cache ==> get bikes available from cache as well to avoid inconsistencies
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
l_oBikesOccupiedResponse.Source,
|
||||
bikesOccupiedResponse.Source,
|
||||
new StationsAndBikesContainer(
|
||||
(await server.GetStations(true)).Response.GetStationsAllMutable(),
|
||||
UpdaterJSON.GetBikesAll(
|
||||
(await server.GetBikesAvailable(true)).Response,
|
||||
l_oBikesOccupiedResponse.Response,
|
||||
bikesOccupiedResponse.Response,
|
||||
Mail,
|
||||
DateTimeProvider)),
|
||||
l_oBikesOccupiedResponse.Exception);
|
||||
bikesOccupiedResponse.Exception);
|
||||
}
|
||||
|
||||
// Both types bikes could read from copri => update cache
|
||||
server.AddToCache(resultStations);
|
||||
server.AddToCache(l_oBikesAvailableResponse);
|
||||
server.AddToCache(l_oBikesOccupiedResponse);
|
||||
server.AddToCache(stationsResponse);
|
||||
server.AddToCache(bikesAvailableResponse);
|
||||
server.AddToCache(bikesOccupiedResponse);
|
||||
|
||||
var exceptions = new[] { resultStations?.Exception, l_oBikesAvailableResponse?.Exception, l_oBikesOccupiedResponse?.Exception }.Where(x => x != null).ToArray();
|
||||
var exceptions = new[] { stationsResponse?.Exception, bikesAvailableResponse?.Exception, bikesOccupiedResponse?.Exception }.Where(x => x != null).ToArray();
|
||||
|
||||
var stationsMutable = stationsResponse.Response.GetStationsAllMutable();
|
||||
var bikesMutable = UpdaterJSON.GetBikesAll(
|
||||
bikesAvailableResponse.Response,
|
||||
bikesOccupiedResponse.Response,
|
||||
Mail,
|
||||
DateTimeProvider);
|
||||
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
resultStations.Source,
|
||||
new StationsAndBikesContainer(
|
||||
resultStations.Response.GetStationsAllMutable(),
|
||||
UpdaterJSON.GetBikesAll(
|
||||
l_oBikesAvailableResponse.Response,
|
||||
l_oBikesOccupiedResponse.Response,
|
||||
Mail,
|
||||
DateTimeProvider)),
|
||||
stationsResponse.Source,
|
||||
new StationsAndBikesContainer(stationsMutable, bikesMutable),
|
||||
exceptions.Length > 0 ? new AggregateException(exceptions) : null);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ using System.Collections.Generic;
|
|||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Model.Repository;
|
||||
using TINK.Repository;
|
||||
using BikeInfo = TINK.Model.Bike.BC.BikeInfo;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
|
@ -44,7 +44,7 @@ namespace TINK.Model.Connector
|
|||
Log.ForContext<Query>().Error("Unexpected call to get be bikes occpied detected. No user is logged in.");
|
||||
return new Result<BikeCollection>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
await Task.Run(() => new BikeCollection(new Dictionary<int, BikeInfo>())),
|
||||
await Task.Run(() => new BikeCollection(new Dictionary<string, BikeInfo>())),
|
||||
new System.Exception("Abfrage der reservierten/ gebuchten Räder fehlgeschlagen. Kein Benutzer angemeldet."));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Model.Repository;
|
||||
using TINK.Repository;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
|
|
@ -5,8 +5,8 @@ using System.Globalization;
|
|||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.Repository.Exception;
|
||||
using TINK.Model.Repository.Response;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Response;
|
||||
using TINK.Model.Services.CopriApi.ServerUris;
|
||||
using TINK.Model.State;
|
||||
|
||||
|
@ -51,14 +51,16 @@ namespace TINK.Model.Connector
|
|||
/// <summary> Gets the position from StationInfo object. </summary>
|
||||
/// <param name="p_oAuthorizationResponse">Object to get information from.</param>
|
||||
/// <returns>Position information.</returns>
|
||||
public static IEnumerable<string> GetGroup(this string p_oGroup)
|
||||
public static IEnumerable<string> GetGroup(this string[] group)
|
||||
{
|
||||
if (string.IsNullOrEmpty(p_oGroup))
|
||||
if (group == null || group.Length == 0)
|
||||
{
|
||||
throw new ArgumentException("Can not get goup form string. Group text can not be null.");
|
||||
// If not logged in stations groups are empty form COPRI version v4.1.
|
||||
Log.Debug("Can not get goup form string. Group text can not be null.");
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
return new HashSet<string>(p_oGroup.Split(',')).ToList();
|
||||
return new HashSet<string>(group).ToList();
|
||||
}
|
||||
|
||||
/// <summary> Gets the position from StationInfo object. </summary>
|
||||
|
@ -78,9 +80,9 @@ namespace TINK.Model.Connector
|
|||
{
|
||||
return p_oStationInfo.station_group.GetGroup();
|
||||
}
|
||||
catch (System.Exception l_oException)
|
||||
catch (Exception l_oException)
|
||||
{
|
||||
throw new System.Exception($"Can not get group of stations from text \"{p_oStationInfo.station_group}\".", l_oException);
|
||||
throw new Exception($"Can not get group of stations from text \"{p_oStationInfo.station_group}\".", l_oException);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,24 +312,19 @@ namespace TINK.Model.Connector
|
|||
/// </summary>
|
||||
/// <param name="p_strGps">Text to extract positon from.</param>
|
||||
/// <returns>Position object.</returns>
|
||||
public static Station.Position GetPosition(string p_strGps)
|
||||
public static Station.Position GetPosition(GpsInfo gps)
|
||||
{
|
||||
if (p_strGps == null)
|
||||
if (gps == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var l_oPosition = p_strGps.Split(',');
|
||||
|
||||
if (l_oPosition.Length != 2)
|
||||
return null;
|
||||
|
||||
double l_oLatitude;
|
||||
if (!double.TryParse(l_oPosition[0], NumberStyles.Float, CultureInfo.InvariantCulture, out l_oLatitude))
|
||||
if (!double.TryParse(gps.latitude, NumberStyles.Float, CultureInfo.InvariantCulture, out l_oLatitude))
|
||||
return null;
|
||||
|
||||
double l_oLongitude;
|
||||
if (!double.TryParse(l_oPosition[1], NumberStyles.Float, CultureInfo.InvariantCulture, out l_oLongitude))
|
||||
if (!double.TryParse(gps.longitude, NumberStyles.Float, CultureInfo.InvariantCulture, out l_oLongitude))
|
||||
return null;
|
||||
|
||||
return new Station.Position(l_oLatitude, l_oLongitude);
|
||||
|
@ -354,5 +351,15 @@ namespace TINK.Model.Connector
|
|||
? new Uri($"{bikeInfo.uri_operator}/{CopriServerUriList.REST_RESOURCE_ROOT}")
|
||||
: null;
|
||||
}
|
||||
|
||||
/// <summary> Gets the copriversion from.</summary>
|
||||
/// <param name="response">Response to get version info from.</param>
|
||||
/// <returns>COPRI version</returns>
|
||||
public static Version GetCopriVersion(this CopriVersion response)
|
||||
=> response!= null
|
||||
&& !string.IsNullOrEmpty(response.copri_version)
|
||||
&& Version.TryParse(response.copri_version, out Version copriVersion)
|
||||
? copriVersion
|
||||
: throw new InvalidResponseException($"Can not get version info from copri response {response?.copri_version}.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
using System;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.Station;
|
||||
using TINK.Model.Repository.Response;
|
||||
using TINK.Repository.Response;
|
||||
using TINK.Model.User.Account;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model.State;
|
||||
using TINK.Model.Repository.Exception;
|
||||
using TINK.Repository.Exception;
|
||||
using Serilog;
|
||||
|
||||
using BikeInfo = TINK.Model.Bike.BC.BikeInfo;
|
||||
|
@ -190,8 +190,8 @@ namespace TINK.Model.Connector
|
|||
string p_strMail,
|
||||
Func<DateTime> p_oDateTimeProvider)
|
||||
{
|
||||
var l_oBikesDictionary = new Dictionary<int, BikeInfo>();
|
||||
var l_oDuplicates = new Dictionary<int, BikeInfo>();
|
||||
var l_oBikesDictionary = new Dictionary<string, BikeInfo>();
|
||||
var l_oDuplicates = new Dictionary<string, BikeInfo>();
|
||||
|
||||
// Get bikes from Copri/ file/ memory, ....
|
||||
if (p_oBikesAvailableResponse != null
|
||||
|
@ -295,7 +295,7 @@ namespace TINK.Model.Connector
|
|||
return null;
|
||||
}
|
||||
|
||||
if (bikeInfo.station == null)
|
||||
if (string.IsNullOrEmpty(bikeInfo.station))
|
||||
{
|
||||
// Bike available must always have a station id because bikes can only be returned at a station.
|
||||
Log.Error($"Can not create new {nameof(BikeInfo)}-object from {nameof(BikeInfoAvailable)} argument. No station info set.");
|
||||
|
@ -485,7 +485,11 @@ namespace TINK.Model.Connector
|
|||
return new Bikes.Bike.TariffDescription
|
||||
{
|
||||
Name = tariffDesciption?.name,
|
||||
#if USCSHARP9
|
||||
Number = int.TryParse(tariffDesciption?.number, out int number) ? number : null,
|
||||
#else
|
||||
Number = int.TryParse(tariffDesciption?.number, out int number) ? number : (int?) null,
|
||||
#endif
|
||||
FreeTimePerSession = double.TryParse(tariffDesciption?.free_hours, NumberStyles.Any, CultureInfo.InvariantCulture, out double freeHours) ? TimeSpan.FromHours(freeHours) : TimeSpan.Zero,
|
||||
FeeEuroPerHour = double.TryParse(tariffDesciption?.eur_per_hour, NumberStyles.Any, CultureInfo.InvariantCulture, out double euroPerHour) ? euroPerHour : double.NaN,
|
||||
AboEuroPerMonth = double.TryParse(tariffDesciption?.abo_eur_per_month, NumberStyles.Any, CultureInfo.InvariantCulture, out double aboEuroPerMonth) ? aboEuroPerMonth : double.NaN,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue