diff --git a/Fitbit.NetCore/Fitbit.NetCore.csproj b/Fitbit.NetCore/Fitbit.NetCore.csproj
index 125143c4..503297fe 100644
--- a/Fitbit.NetCore/Fitbit.NetCore.csproj
+++ b/Fitbit.NetCore/Fitbit.NetCore.csproj
@@ -19,6 +19,11 @@
..\NuGet
+
+ true
+
+
+
%(RecursiveDir)%(Filename)%(Extension)
diff --git a/Fitbit.Portable.Tests/Helpers/ResponseFaker.cs b/Fitbit.Portable.Tests/Helpers/ResponseFaker.cs
index 6ca55ce4..4efbc639 100644
--- a/Fitbit.Portable.Tests/Helpers/ResponseFaker.cs
+++ b/Fitbit.Portable.Tests/Helpers/ResponseFaker.cs
@@ -17,7 +17,7 @@ public class ResponseFaker : IFitbitInterceptor
public ResponseFaker(string content, HttpStatusCode code = HttpStatusCode.OK)
{
var c = new StringContent(content);
- this.fakeResponse = new HttpResponseMessage(code) { Content = c };
+ fakeResponse = new HttpResponseMessage(code) { Content = c };
}
public ResponseFaker(HttpResponseMessage fakeResponse = null)
diff --git a/Fitbit.Portable.Tests/InterceptorCounter.cs b/Fitbit.Portable.Tests/InterceptorCounter.cs
index 78baf743..bb4e4b98 100644
--- a/Fitbit.Portable.Tests/InterceptorCounter.cs
+++ b/Fitbit.Portable.Tests/InterceptorCounter.cs
@@ -21,7 +21,7 @@ public Task InterceptRequest(HttpRequestMessage request, Ca
public async Task InterceptResponse(Task response, CancellationToken cancellationToken, FitbitClient client)
{
ResponseCount++;
- this.responseContent = await response.Result.Content.ReadAsStringAsync();
+ responseContent = await response.Result.Content.ReadAsStringAsync();
return null;
}
}
diff --git a/Fitbit.Portable.Tests/RemoveSubscriptionTests.cs b/Fitbit.Portable.Tests/RemoveSubscriptionTests.cs
index 42ffd200..bcdff8dd 100644
--- a/Fitbit.Portable.Tests/RemoveSubscriptionTests.cs
+++ b/Fitbit.Portable.Tests/RemoveSubscriptionTests.cs
@@ -23,7 +23,7 @@ public void DeleteSubscription_Correctly()
var subId = "320";
var expectedUrl = @"https://api.fitbit.com/1/user/-/apiSubscriptions/"+subId+".json";
- var sut = this.SetupFitbitClient(null, expectedUrl, HttpMethod.Delete);
+ var sut = SetupFitbitClient(null, expectedUrl, HttpMethod.Delete);
//Any unexpected behavior will throw exception or fail on request checks (in handler)
//Pass APICollectionType.user to delete subscriptions for all data sets
@@ -39,7 +39,7 @@ public void DeleteSubscriptonFromSpecificCollection()
var collection = APICollectionType.activities;
var expectedUrl = @"https://api.fitbit.com/1/user/-/"+ collection +@"/apiSubscriptions/" + subId + ".json";
- var sut = this.SetupFitbitClient(null, expectedUrl, HttpMethod.Delete);
+ var sut = SetupFitbitClient(null, expectedUrl, HttpMethod.Delete);
//Any unexpected behavior will throw exception or fail on request checks (in handler)
sut.DeleteSubscriptionAsync(collection, subId).Wait();
diff --git a/Fitbit.Portable/Fitbit.Portable.csproj b/Fitbit.Portable/Fitbit.Portable.csproj
index f650b2fe..15976938 100644
--- a/Fitbit.Portable/Fitbit.Portable.csproj
+++ b/Fitbit.Portable/Fitbit.Portable.csproj
@@ -27,6 +27,7 @@
TRACE;DEBUG;REQUIRES_JSONNET
prompt
4
+ true
pdbonly
diff --git a/Fitbit.Portable/FitbitClient.cs b/Fitbit.Portable/FitbitClient.cs
index 2ca91a5f..30153f0a 100644
--- a/Fitbit.Portable/FitbitClient.cs
+++ b/Fitbit.Portable/FitbitClient.cs
@@ -13,21 +13,20 @@ namespace Fitbit.Api.Portable
{
public class FitbitClient : IFitbitClient
{
- public FitbitAppCredentials AppCredentials { get; private set; }
+ public FitbitAppCredentials AppCredentials { get; }
private OAuth2AccessToken _accesToken;
public OAuth2AccessToken AccessToken
{
- get
- {
- return _accesToken;
- }
+ get { return _accesToken; }
set
{
_accesToken = value;
//If we update the AccessToken after HttpClient has been created, then reconfigure authorization header
if (HttpClient != null)
+ {
ConfigureAuthorizationHeader();
+ }
}
}
@@ -37,10 +36,10 @@ public OAuth2AccessToken AccessToken
public HttpClient HttpClient { get; private set; }
public ITokenManager TokenManager { get; private set; }
- public bool OAuth2TokenAutoRefresh { get; set; }
- public List FitbitInterceptorPipeline { get; private set; }
+ public bool OAuth2TokenAutoRefresh { get; set; }
+ public List FitbitInterceptorPipeline { get; } = new List();
///
/// Simplest constructor for OAuth2- requires the minimum information required by FitBit.Net client to make succesful calls to Fitbit Api
@@ -48,17 +47,16 @@ public OAuth2AccessToken AccessToken
/// Obtain this information from your developer dashboard. App credentials are required to perform token refresh
/// Authenticate with Fitbit API using OAuth2. Authenticator2 class is a helper for this process
/// An interface that enables sniffing all outgoing and incoming http requests from FitbitClient
+ /// Enable auto refresh for the OAuth2 auhtorization token
+ /// ITokenManager implementation; if none provided an instance of DefaultTokenManager is used
public FitbitClient(FitbitAppCredentials credentials, OAuth2AccessToken accessToken, IFitbitInterceptor interceptor = null, bool enableOAuth2TokenRefresh = true, ITokenManager tokenManager = null)
{
- this.AppCredentials = credentials;
- this.AccessToken = accessToken;
-
- this.FitbitInterceptorPipeline = new List();
-
-
+ AppCredentials = credentials;
+ AccessToken = accessToken;
+
if(interceptor != null)
{
- this.FitbitInterceptorPipeline.Add(interceptor);
+ FitbitInterceptorPipeline.Add(interceptor);
}
ConfigureTokenManager(tokenManager);
@@ -71,10 +69,11 @@ public FitbitClient(FitbitAppCredentials credentials, OAuth2AccessToken accessTo
private void ConfigureAutoRefresh(bool enableOAuth2TokenRefresh)
{
- this.OAuth2TokenAutoRefresh = enableOAuth2TokenRefresh;
- if(OAuth2TokenAutoRefresh)
- this.FitbitInterceptorPipeline.Add(new OAuth2AutoRefreshInterceptor());
- return;
+ OAuth2TokenAutoRefresh = enableOAuth2TokenRefresh;
+ if (OAuth2TokenAutoRefresh)
+ {
+ FitbitInterceptorPipeline.Add(new OAuth2AutoRefreshInterceptor());
+ }
}
///
@@ -85,13 +84,15 @@ private void ConfigureAutoRefresh(bool enableOAuth2TokenRefresh)
/// An interface that enables sniffing all outgoing and incoming http requests from FitbitClient
public FitbitClient(FitbitAppCredentials credentials, OAuth2AccessToken accessToken, List interceptors, bool enableOAuth2TokenRefresh = true, ITokenManager tokenManager = null)
{
- this.AppCredentials = credentials;
- this.AccessToken = accessToken;
+ AppCredentials = credentials;
+ AccessToken = accessToken;
- this.FitbitInterceptorPipeline = new List();
+ FitbitInterceptorPipeline = new List();
- if(interceptors != null && interceptors.Count > 0)
- this.FitbitInterceptorPipeline.AddRange(interceptors);
+ if (interceptors != null && interceptors.Count > 0)
+ {
+ FitbitInterceptorPipeline.AddRange(interceptors);
+ }
ConfigureTokenManager(tokenManager);
@@ -100,7 +101,6 @@ public FitbitClient(FitbitAppCredentials credentials, OAuth2AccessToken accessTo
CreateHttpClientForOAuth2();
}
-
public FitbitClient(FitbitAppCredentials credentials, OAuth2AccessToken accessToken, bool enableOAuth2TokenRefresh) : this(credentials, accessToken, null, enableOAuth2TokenRefresh)
{
@@ -126,12 +126,12 @@ public FitbitClient(FitbitAppCredentials credentials, OAuth2AccessToken accessTo
///
/// A function or lambda expression who is in charge of creating th HttpClient. It takes as an argument a HttpMessageHandler which does wiring for IFitbitInterceptor. To use IFitbitInterceptor you must pass this HttpMessageHandler as anargument to the constuctor of HttpClient
/// An interface that enables sniffing all outgoing and incoming http requests from FitbitClient
- public FitbitClient(Func customFactory, IFitbitInterceptor interceptor = null, ITokenManager tokenManager = null)
+ internal FitbitClient(Func customFactory, IFitbitInterceptor interceptor = null, ITokenManager tokenManager = null)
{
- this.OAuth2TokenAutoRefresh = false;
+ OAuth2TokenAutoRefresh = false;
ConfigureTokenManager(tokenManager);
- this.HttpClient = customFactory(new FitbitHttpMessageHandler(this, interceptor));
+ HttpClient = customFactory(new FitbitHttpMessageHandler(this, interceptor));
}
private void ConfigureTokenManager(ITokenManager tokenManager)
@@ -142,10 +142,7 @@ private void ConfigureTokenManager(ITokenManager tokenManager)
private void CreateHttpClientForOAuth2()
{
var pipeline = this.CreatePipeline(FitbitInterceptorPipeline);
- if (pipeline != null)
- this.HttpClient = new HttpClient(pipeline);
- else
- this.HttpClient = new HttpClient();
+ HttpClient = pipeline != null ? new HttpClient(pipeline) : new HttpClient();
ConfigureAuthorizationHeader();
}
@@ -202,16 +199,14 @@ public async Task GetDayActivitySummaryAsync(DateTime activityD
///
public async Task GetActivitiesStatsAsync(string encodedUserId = null)
{
- string apiCall = FitbitClientHelperExtensions.ToFullUrl("/1/user/{0}/activities.json", encodedUserId);
+ string apiCall = FitbitClientHelperExtensions.ToFullUrl("/1/user/{0}/activities.json", encodedUserId);
HttpResponseMessage response = await HttpClient.GetAsync(apiCall);
await HandleResponse(response);
string responseBody = await response.Content.ReadAsStringAsync();
var serializer = new JsonDotNetSerializer();
return serializer.Deserialize(responseBody);
}
-
- #region Sleep
-
+
///
/// Requests the sleep data for the specified date for the logged in user
/// NOTE: This is for the V1 of the sleep api which is now Deprecated
@@ -270,7 +265,6 @@ public async Task GetSleepDateRangeAsync(DateTime startDate,
return data;
}
-
///
/// The Get Sleep Logs List endpoint returns a list of a user's sleep logs (including naps)
/// before or after a given day with offset, limit, and sort order.
@@ -329,7 +323,6 @@ public async Task GetSleepLogListAsync(DateTime dateToList, Sl
return data;
}
-
///
/// Creates a log entry for a sleep event and returns a response in the format requested
///
@@ -352,9 +345,7 @@ public async Task PostLogSleepAsync(string startTime, int dur
return serialzer.Deserialize(responeBody);
}
-
- #endregion Sleep
-
+
///
/// Requests the devices for the current logged in user
///
@@ -424,14 +415,22 @@ public async Task GetHeartRateIntraday(DateTime date, H
string resolutionText = null;
//this little big of section is necessary because enums can't start with numbers
- if (resolution == HeartRateResolution.oneSecond)
- resolutionText = "1sec";
- else if (resolution == HeartRateResolution.oneMinute)
- resolutionText = "1min";
- else
- resolutionText = "15min";
+ switch (resolution)
+ {
+ case HeartRateResolution.oneSecond:
+ resolutionText = "1sec";
+ break;
- string apiCall = String.Format("https://api.fitbit.com/1.1/user/-/activities/heart/date/{0}/{1}/{2}/time/00:00:00/23:59:59.json", date.ToString("yyyy-MM-dd"), date.ToString("yyyy-MM-dd"), resolutionText);
+ case HeartRateResolution.oneMinute:
+ resolutionText = "1min";
+ break;
+
+ default:
+ resolutionText = "15min";
+ break;
+ }
+
+ string apiCall = string.Format("https://api.fitbit.com/1.1/user/-/activities/heart/date/{0}/{1}/{2}/time/00:00:00/23:59:59.json", date.ToString("yyyy-MM-dd"), date.ToString("yyyy-MM-dd"), resolutionText);
HttpResponseMessage response = await HttpClient.GetAsync(apiCall);
await HandleResponse(response);
@@ -501,8 +500,7 @@ public async Task GetHeartRateIntraday(DateTime date, H
string responseBody = await response.Content.ReadAsStringAsync();
var serializer = new JsonDotNetSerializer {RootProperty = timeSeriesResourceType.ToTimeSeriesProperty()};
- return serializer.GetTimeSeriesDataList(responseBody);
-
+ return serializer.GetTimeSeriesDataList(responseBody);
}
///
@@ -554,8 +552,8 @@ public async Task GetIntraDayTimeSeriesAsync(IntradayResourceType
{
string apiCall;
- if (intraDayTimeSpan > new TimeSpan(0, 1, 0) && //the timespan is greater than a minute
- dayAndStartTime.Day == dayAndStartTime.Add(intraDayTimeSpan).Day) //adding the timespan doesn't go in to the next day
+ if (intraDayTimeSpan > new TimeSpan(0, 1, 0) //the timespan is greater than a minute
+ && dayAndStartTime.Day == dayAndStartTime.Add(intraDayTimeSpan).Day) //adding the timespan doesn't go in to the next day
{
apiCall = string.Format("/1/user/-{0}/date/{1}/1d/time/{2}/{3}.json",
timeSeriesResourceType.GetStringValue(),
@@ -572,7 +570,7 @@ public async Task GetIntraDayTimeSeriesAsync(IntradayResourceType
apiCall = FitbitClientHelperExtensions.ToFullUrl(apiCall);
- HttpResponseMessage response = null;
+ HttpResponseMessage response;
try
{
response = await HttpClient.GetAsync(apiCall);
@@ -583,11 +581,9 @@ public async Task GetIntraDayTimeSeriesAsync(IntradayResourceType
{
return null;
}
- else
- {
- //otherwise, rethrow because we only want to alter behavior for the very specific case above
- throw;
- }
+
+ //otherwise, rethrow because we only want to alter behavior for the very specific case above
+ throw;
}
await HandleResponse(response);
string responseBody = await response.Content.ReadAsStringAsync();
@@ -599,16 +595,15 @@ public async Task GetIntraDayTimeSeriesAsync(IntradayResourceType
var serializer = new JsonDotNetSerializer { RootProperty = timeSeriesResourceType.ToTimeSeriesProperty() };
- IntradayData data = null;
+ IntradayData data;
try
{
data = serializer.GetIntradayTimeSeriesData(responseBody);
}
- catch(Exception ex)
+ catch(Exception exception)
{
- FitbitRequestException fEx = new FitbitRequestException(response, null, "Serialization Error in GetIntradayTimeSeriesData", ex);
- throw fEx;
+ throw new FitbitRequestException(response, null, "Serialization Error in GetIntradayTimeSeriesData", exception);
}
return data;
@@ -940,12 +935,7 @@ public async Task> GetSubscriptionsAsync()
public async Task DeleteSubscriptionAsync(APICollectionType collection, string uniqueSubscriptionId, string subscriberId = null)
{
- var collectionString = string.Empty;
-
- if (collection == APICollectionType.user)
- collectionString = string.Empty;
- else
- collectionString = collection.ToString() + @"/";
+ var collectionString = collection == APICollectionType.user ? string.Empty : collection + @"/";
string url = "/1/user/-/{2}apiSubscriptions/{1}.json";
string apiCall = FitbitClientHelperExtensions.ToFullUrl(url, args: new object[] { uniqueSubscriptionId, collectionString });
@@ -1024,6 +1014,5 @@ private async Task HandleResponse(HttpResponseMessage response)
throw new FitbitException($"An error has occured. Please see error list for details - {response.StatusCode}", errors);
}
}
-
}
}
\ No newline at end of file
diff --git a/Fitbit.Portable/FitbitHttpMessageHandler.cs b/Fitbit.Portable/FitbitHttpMessageHandler.cs
index 804b76af..58ec268d 100644
--- a/Fitbit.Portable/FitbitHttpMessageHandler.cs
+++ b/Fitbit.Portable/FitbitHttpMessageHandler.cs
@@ -1,28 +1,20 @@
namespace Fitbit.Api.Portable
{
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- using System;
- using System.Collections.Generic;
using System.Diagnostics;
- using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
internal class FitbitHttpMessageHandler : DelegatingHandler
{
- private IFitbitInterceptor interceptor;
- Func, CancellationToken, Task> responseHandler;
+ private readonly IFitbitInterceptor _interceptor;
-
- public FitbitClient FitbitClient { get; private set; }
+ public FitbitClient FitbitClient { get; }
public FitbitHttpMessageHandler(FitbitClient fitbitClient, IFitbitInterceptor interceptor)
{
- this.FitbitClient = fitbitClient;
- this.interceptor = interceptor;
- responseHandler = ResponseHandler;
+ FitbitClient = fitbitClient;
+ _interceptor = interceptor;
//Define the inner must handler. Otherwise exception is thrown.
InnerHandler = new HttpClientHandler();
}
@@ -34,23 +26,20 @@ protected override Task SendAsync(HttpRequestMessage reques
Task interceptorFakeResponse = null;
Debug.WriteLine("Entering Http client's request message handler. Request details: {0}", request.ToString());
- if (interceptor != null)
- interceptorFakeResponse = interceptor.InterceptRequest(request, cancellationToken, FitbitClient);
+ if (_interceptor != null)
+ {
+ interceptorFakeResponse = _interceptor.InterceptRequest(request, cancellationToken, FitbitClient);
+ }
if (interceptorFakeResponse != null) //then highjack the request pipeline and return the HttpResponse returned by interceptor. Invoke Response handler at return.
{
//If we are faking the response, have the courtesy of setting the original HttpRequestMessage
interceptorFakeResponse.Result.RequestMessage = request;
- return interceptorFakeResponse.ContinueWith(
- responseTask => ResponseHandler(responseTask, cancellationToken).Result
- );
- }
- else //Let the base object continue with the request pipeline. Invoke Response handler at return.
- {
- return base.SendAsync(request, cancellationToken).ContinueWith(
- responseTask => ResponseHandler(responseTask, cancellationToken).Result
- );
+ return interceptorFakeResponse.ContinueWith(responseTask => ResponseHandler(responseTask, cancellationToken).Result, cancellationToken);
}
+
+ //Let the base object continue with the request pipeline. Invoke Response handler at return.
+ return base.SendAsync(request, cancellationToken).ContinueWith(responseTask => ResponseHandler(responseTask, cancellationToken).Result, cancellationToken);
}
//Handle the following method with EXTREME care as it will be invoked on ALL responses made by FitbitClient
@@ -58,9 +47,9 @@ private async Task ResponseHandler(Task ResponseHandler(Task requestTask)
{
- string responseContent = null;
-
- if (requestTask.Result.Content != null)
- responseContent = requestTask.Result.Content.ReadAsStringAsync().Result;
+ var responseContent = requestTask?.Result?.Content?.ReadAsStringAsync().Result;
- Debug.WriteLine("Entering Http client's response message handler. Response details: \n {0}", requestTask.Result);
+ Debug.WriteLine("Entering Http client's response message handler. Response details: \n {0}", requestTask?.Result);
Debug.WriteLine("Response Content: \n {0}", responseContent ?? "Response body was empty");
}
}
diff --git a/Fitbit.Portable/FitbitRequestException.cs b/Fitbit.Portable/FitbitRequestException.cs
index 5e865199..65eb6821 100644
--- a/Fitbit.Portable/FitbitRequestException.cs
+++ b/Fitbit.Portable/FitbitRequestException.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using System.Net;
using System.Net.Http;
using Fitbit.Models;
using System;
@@ -13,7 +12,7 @@ public class FitbitRequestException : FitbitException
public FitbitRequestException(HttpResponseMessage response, IEnumerable errors, string message = default(string), Exception innerEx = null)
: base(message ?? $"Fitbit Request exception - Http Status Code: {response.StatusCode} - see errors for more details.", errors, innerEx)
{
- this.Response = response;
+ Response = response;
}
}
}
\ No newline at end of file
diff --git a/Fitbit.Portable/Interceptors/FitbitHttpErrorHandler.cs b/Fitbit.Portable/Interceptors/FitbitHttpErrorHandler.cs
index d236f88f..23914b7b 100644
--- a/Fitbit.Portable/Interceptors/FitbitHttpErrorHandler.cs
+++ b/Fitbit.Portable/Interceptors/FitbitHttpErrorHandler.cs
@@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Net;
using System.Net.Http;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Fitbit.Models;
@@ -19,37 +16,33 @@ public Task InterceptRequest(HttpRequestMessage request, Ca
public async Task InterceptResponse(Task response, CancellationToken cancellationToken, FitbitClient invokingClient)
{
- if ((await response).IsSuccessStatusCode) return null;
- else
+ if ((await response).IsSuccessStatusCode)
{
- await GenerateFitbitRequestException(await response);
return null;
}
-
+ await GenerateFitbitRequestException(await response);
+ return null;
}
-
-
+
private async Task GenerateFitbitRequestException(HttpResponseMessage response)
{
- List errors = null;
+ List errors;
try
{
// assumption is error response from fitbit in the 4xx range
errors = new JsonDotNetSerializer().ParseErrors(await response.Content.ReadAsStringAsync());
}
- catch(ArgumentNullException emptyBodyException)
+ catch(ArgumentNullException)
{
- errors = new List() { {new ApiError() {ErrorType = "Fitbit.Net client library error", Message = "Error parsing content body. The content was empty"} } };
+ errors = new List { new ApiError {ErrorType = "Fitbit.Net client library error", Message = "Error parsing content body. The content was empty" }};
}
- catch (Exception e)
+ catch (Exception)
{
- errors = new List() { { new ApiError() { ErrorType = "Fitbit.Net client library error", Message = "Unexpected error when deserializing the content of Fitbit's response." } } };
+ errors = new List { new ApiError { ErrorType = "Fitbit.Net client library error", Message = "Unexpected error when deserializing the content of Fitbit's response." }};
}
- var exception = new FitbitRequestException(response, errors);
-
- throw exception;
+ throw new FitbitRequestException(response, errors);
}
}
}
diff --git a/Fitbit.Portable/JsonDotNetSerializerExtensions.cs b/Fitbit.Portable/JsonDotNetSerializerExtensions.cs
index 40ed1d2b..4dc975e1 100644
--- a/Fitbit.Portable/JsonDotNetSerializerExtensions.cs
+++ b/Fitbit.Portable/JsonDotNetSerializerExtensions.cs
@@ -18,15 +18,13 @@ internal static List ParseErrors(this JsonDotNetSerializer serializer,
{
if (string.IsNullOrWhiteSpace(errorJson))
{
- throw new ArgumentNullException(nameof(errorJson), "errorJson can not be empty, null or whitespace");
+ throw new ArgumentNullException(nameof(errorJson), $"{nameof(errorJson)} can not be empty, null or whitespace");
}
serializer.RootProperty = "errors";
return serializer.Deserialize>(errorJson);
}
-
-
-
+
///
/// GetFat has to doe some custom manipulation with the returned representation
///
@@ -37,7 +35,7 @@ internal static Fat GetFat(this JsonDotNetSerializer serializer, string fatJson)
{
if (string.IsNullOrWhiteSpace(fatJson))
{
- throw new ArgumentNullException(nameof(fatJson), "fatJson can not be empty, null or whitespace");
+ throw new ArgumentNullException(nameof(fatJson), $"{nameof(fatJson)} can not be empty, null or whitespace");
}
var fatlogs = JToken.Parse(fatJson)["fat"];
@@ -56,7 +54,7 @@ internal static Weight GetWeight(this JsonDotNetSerializer serializer, string we
{
if (string.IsNullOrWhiteSpace(weightJson))
{
- throw new ArgumentNullException(nameof(weightJson), "weightJson can not be empty, null or whitespace");
+ throw new ArgumentNullException(nameof(weightJson), $"{nameof(weightJson)} can not be empty, null or whitespace");
}
var weightlogs = JToken.Parse(weightJson)["weight"];
@@ -75,7 +73,7 @@ internal static List GetFriends(this JsonDotNetSerializer serialize
{
if (string.IsNullOrWhiteSpace(friendsJson))
{
- throw new ArgumentNullException(nameof(friendsJson), "friendsJson can not be empty, null or whitespace.");
+ throw new ArgumentNullException(nameof(friendsJson), $"{nameof(friendsJson)} can not be empty, null or whitespace.");
}
serializer.RootProperty = "user";
@@ -83,21 +81,18 @@ internal static List GetFriends(this JsonDotNetSerializer serialize
return friends.Children().Select(serializer.Deserialize).ToList();
}
-
-
-
-
///
/// GetTimeSeriesDataList has to do some custom manipulation with the returned representation
///
///
- ///
+ ///
+ ///
///
internal static HeartActivitiesIntraday GetHeartRateIntraday(this JsonDotNetSerializer serializer, DateTime date, string heartRateIntradayJson)
{
if (string.IsNullOrWhiteSpace(heartRateIntradayJson))
{
- throw new ArgumentNullException("heartRateIntradayJson", "heartRateIntradayJson can not be empty, null or whitespace.");
+ throw new ArgumentNullException(nameof(heartRateIntradayJson), $"{nameof(heartRateIntradayJson)} can not be empty, null or whitespace.");
}
var activitiesHeartIntraday = JToken.Parse(heartRateIntradayJson)["activities-heart-intraday"];
@@ -108,7 +103,7 @@ internal static HeartActivitiesIntraday GetHeartRateIntraday(this JsonDotNetSeri
Dataset = (from item in dataset
select new DatasetInterval
{
- Time = DateTime.Parse(date.ToString("yyyy-MM-dd") + " " + item["time"].ToString()), //here, maybe pass in the date so we have a full object of date and time
+ Time = DateTime.Parse(date.ToString("yyyy-MM-dd") + " " + item["time"]), //here, maybe pass in the date so we have a full object of date and time
Value = int.Parse(item["value"].ToString())
}).ToList(),
DatasetInterval = Convert.ToInt32(activitiesHeartIntraday["datasetInterval"]),
@@ -118,13 +113,12 @@ internal static HeartActivitiesIntraday GetHeartRateIntraday(this JsonDotNetSeri
return result;
}
-
-
+
internal static HeartActivitiesTimeSeries GetHeartActivitiesTimeSeries(this JsonDotNetSerializer serializer, string heartActivitiesTimeSeries)
{
if (string.IsNullOrWhiteSpace(heartActivitiesTimeSeries))
{
- throw new ArgumentNullException("heartActivitiesTimeSeries", "heartActivitiesTimeSeries can not be empty, null or whitespace.");
+ throw new ArgumentNullException(nameof(heartActivitiesTimeSeries), $"{nameof(heartActivitiesTimeSeries)} can not be empty, null or whitespace.");
}
var activitiesHeartIntraday = JToken.Parse(heartActivitiesTimeSeries)["activities-heart"];
@@ -143,10 +137,7 @@ internal static HeartActivitiesTimeSeries GetHeartActivitiesTimeSeries(this Json
return result;
}
-
-
-
-
+
///
/// GetTimeSeriesDataList has to do some custom manipulation with the returned representation
///
@@ -157,7 +148,7 @@ internal static TimeSeriesDataList GetTimeSeriesDataList(this JsonDotNetSerializ
{
if (string.IsNullOrWhiteSpace(timeSeriesDataJson))
{
- throw new ArgumentNullException(nameof(timeSeriesDataJson), "timeSeriesDataJson can not be empty, null or whitespace.");
+ throw new ArgumentNullException(nameof(timeSeriesDataJson), $"{nameof(timeSeriesDataJson)} can not be empty, null or whitespace.");
}
var dataPoints = JToken.Parse(timeSeriesDataJson)[serializer.RootProperty];
@@ -184,7 +175,7 @@ internal static TimeSeriesDataListInt GetTimeSeriesDataListInt(this JsonDotNetSe
{
if (string.IsNullOrWhiteSpace(timeSeriesDataJson))
{
- throw new ArgumentNullException(nameof(timeSeriesDataJson), "timeSeriesDataJson can not be empty, null or whitespace.");
+ throw new ArgumentNullException(nameof(timeSeriesDataJson), $"{nameof(timeSeriesDataJson)} can not be empty, null or whitespace.");
}
var dataPoints = JToken.Parse(timeSeriesDataJson)[serializer.RootProperty];
@@ -200,15 +191,12 @@ internal static TimeSeriesDataListInt GetTimeSeriesDataListInt(this JsonDotNetSe
return result;
}
-
-
-
-
+
internal static IntradayData GetIntradayTimeSeriesData(this JsonDotNetSerializer serializer, string intradayDataJson)
{
if (string.IsNullOrWhiteSpace(intradayDataJson))
{
- throw new ArgumentNullException(nameof(intradayDataJson), "intradayDataJson can not be empty, null or whitespace.");
+ throw new ArgumentNullException(nameof(intradayDataJson), $"{nameof(intradayDataJson)} can not be empty, null or whitespace.");
}
var parsedJToken = JToken.Parse(intradayDataJson);
@@ -219,7 +207,7 @@ internal static IntradayData GetIntradayTimeSeriesData(this JsonDotNetSerializer
{
date = parsedJToken.SelectToken(serializer.RootProperty).First["dateTime"];
}
- catch (NullReferenceException nullReferenceException)
+ catch (NullReferenceException)
{
//We'll nullref here if we're querying a future date - Fitbit omits dateTime in that case.
//Return null since this error will, in all cases, coincide with an otherwise empty (all zeros) object
@@ -234,8 +222,8 @@ internal static IntradayData GetIntradayTimeSeriesData(this JsonDotNetSerializer
{
Time = DateTime.Parse(date + " " + item["time"]),
Value = item["value"].ToObject().ToString("R"), //converting to double is required to keep precision
- METs = item["mets"] != null ? item["mets"].ToString() : null,
- Level = item["level"] != null ? item["level"].ToString() : null
+ METs = item["mets"]?.ToString(),
+ Level = item["level"]?.ToString()
}).ToList()
};
diff --git a/Fitbit.Portable/OAuth2/DefaultTokenManager.cs b/Fitbit.Portable/OAuth2/DefaultTokenManager.cs
index 20c23128..af55388d 100644
--- a/Fitbit.Portable/OAuth2/DefaultTokenManager.cs
+++ b/Fitbit.Portable/OAuth2/DefaultTokenManager.cs
@@ -37,4 +37,4 @@ public async Task RefreshTokenAsync(FitbitClient client)
return OAuth2Helper.ParseAccessTokenResponse(responseString);
}
}
-}
+}
\ No newline at end of file
diff --git a/Fitbit.Portable/OAuth2/OAuth2Helper.cs b/Fitbit.Portable/OAuth2/OAuth2Helper.cs
index 94d5d2ae..d1d853d9 100644
--- a/Fitbit.Portable/OAuth2/OAuth2Helper.cs
+++ b/Fitbit.Portable/OAuth2/OAuth2Helper.cs
@@ -10,21 +10,20 @@ namespace Fitbit.Api.Portable.OAuth2
public class OAuth2Helper
{
private const string FitbitWebAuthBaseUrl = "https://www.fitbit.com";
- private const string FitbitApiBaseUrl = "https://api.fitbit.com";
-
+ private const string FitbitOauthPostUrl = "https://api.fitbit.com/oauth2/token";
private const string OAuthBase = "/oauth2";
- private string ClientId;
- private string ClientSecret;
-
- private string RedirectUri;
+ private readonly string _clientId;
+ private readonly string _clientSecret;
+ private readonly string _redirectUri;
public OAuth2Helper(FitbitAppCredentials credentials, string redirectUri)
{
- this.ClientId = credentials.ClientId;
- this.ClientSecret = credentials.ClientSecret;
- this.RedirectUri = redirectUri;
+ _clientId = credentials.ClientId;
+ _clientSecret = credentials.ClientSecret;
+ _redirectUri = redirectUri;
}
+
public string GenerateAuthUrl(string[] scopeTypes, string state = null)
{
var sb = new StringBuilder();
@@ -33,12 +32,14 @@ public string GenerateAuthUrl(string[] scopeTypes, string state = null)
sb.Append(OAuthBase);
sb.Append("/authorize?");
sb.Append("response_type=code");
- sb.Append(string.Format("&client_id={0}", this.ClientId));
- sb.Append(string.Format("&redirect_uri={0}", Uri.EscapeDataString(this.RedirectUri)));
+ sb.Append(string.Format("&client_id={0}", _clientId));
+ sb.Append(string.Format("&redirect_uri={0}", Uri.EscapeDataString(_redirectUri)));
sb.Append(string.Format("&scope={0}", String.Join(" ", scopeTypes)));
if (!string.IsNullOrWhiteSpace(state))
+ {
sb.Append(string.Format("&state={0}", state));
+ }
return sb.ToString();
}
@@ -47,33 +48,25 @@ public async Task ExchangeAuthCodeForAccessTokenAsync(string
{
HttpClient httpClient = new HttpClient();
- string postUrl = OAuth2Helper.FitbitOauthPostUrl;
-
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair("grant_type", "authorization_code"),
- new KeyValuePair("client_id", ClientId),
+ new KeyValuePair("client_id", _clientId),
//new KeyValuePair("client_secret", AppSecret),
new KeyValuePair("code", code),
- new KeyValuePair("redirect_uri", this.RedirectUri)
+ new KeyValuePair("redirect_uri", _redirectUri)
});
-
- string clientIdConcatSecret = OAuth2Helper.Base64Encode(ClientId + ":" + ClientSecret);
+ string clientIdConcatSecret = Base64Encode(_clientId + ":" + _clientSecret);
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", clientIdConcatSecret);
- HttpResponseMessage response = await httpClient.PostAsync(postUrl, content);
+ HttpResponseMessage response = await httpClient.PostAsync(FitbitOauthPostUrl, content);
string responseString = await response.Content.ReadAsStringAsync();
- OAuth2AccessToken accessToken = OAuth2Helper.ParseAccessTokenResponse(responseString);
-
- return accessToken;
+ return ParseAccessTokenResponse(responseString);
}
- public static readonly string FitbitOauthPostUrl = "https://api.fitbit.com/oauth2/token";
-
-
public static OAuth2AccessToken ParseAccessTokenResponse(string responseString)
{
// assumption is the errors json will return in usual format eg. errors array
@@ -95,7 +88,7 @@ public static OAuth2AccessToken ParseAccessTokenResponse(string responseString)
///
///
///
- public static string Base64Encode(string plainText)
+ internal static string Base64Encode(string plainText)
{
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(plainTextBytes);
diff --git a/Fitbit.Portable/SubscriptionManager.cs b/Fitbit.Portable/SubscriptionManager.cs
index e93b88e4..36b9040d 100644
--- a/Fitbit.Portable/SubscriptionManager.cs
+++ b/Fitbit.Portable/SubscriptionManager.cs
@@ -1,16 +1,12 @@
using System.Diagnostics;
using System.IO;
-using System.Linq;
-using System.Xml;
using System.Xml.Serialization;
using Fitbit.Api.Portable.Models;
using Fitbit.Models;
+using System.Collections.Generic;
namespace Fitbit.Api.Portable
-{
- using System;
- using System.Collections.Generic;
-
+{
public class SubscriptionManager
{
public List ProcessUpdateReponseBody(string bodyContent)