add openhack files

This commit is contained in:
Ryan Peters
2022-11-03 16:41:13 -04:00
commit b2c9f7e29f
920 changed files with 118861 additions and 0 deletions

View File

@ -0,0 +1,145 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using System;
using MyDriving.DataStore.Abstractions;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.MobileServices;
using Microsoft.WindowsAzure.MobileServices.Sync;
using MyDriving.Utils;
using System.Collections.Generic;
using MyDriving.DataObjects;
using Plugin.Connectivity;
using MyDriving.AzureClient;
using MyDriving.Utils.Interfaces;
namespace MyDriving.DataStore.Azure.Stores
{
public class BaseStore<T> : IBaseStore<T> where T : class, IBaseDataObject, new()
{
IStoreManager storeManager;
IMobileServiceSyncTable<T> table;
protected IMobileServiceSyncTable<T> Table =>
table ?? (table = ServiceLocator.Instance.Resolve<IAzureClient>()?.Client?.GetSyncTable<T>());
public virtual string Identifier => "Items";
public virtual Task<bool> DropTable()
{
table = null;
return Task.FromResult(true);
}
#region IBaseStore implementation
public virtual async Task<bool> RemoveItemsAsync(IEnumerable<T> items)
{
bool result = true;
foreach (var item in items)
{
result = result && await RemoveAsync(item);
}
return result;
}
public async Task InitializeStoreAsync()
{
if (storeManager == null)
storeManager = ServiceLocator.Instance.Resolve<IStoreManager>();
if (!storeManager.IsInitialized)
await storeManager.InitializeAsync();
}
public virtual async Task<IEnumerable<T>> GetItemsAsync(int skip = 0, int take = 100, bool forceRefresh = false)
{
await InitializeStoreAsync();
if (forceRefresh)
{
await SyncAsync();
}
return await Table.ToEnumerableAsync();
}
public virtual async Task<T> GetItemAsync(string id)
{
await InitializeStoreAsync();
await SyncAsync();
var item = await Table.LookupAsync(id);
return item;
}
public virtual async Task<bool> InsertAsync(T item)
{
await InitializeStoreAsync();
await Table.InsertAsync(item); //Insert into the local store
await SyncAsync(); //Send changes to the mobile service
return true;
}
public virtual async Task<bool> UpdateAsync(T item)
{
await InitializeStoreAsync();
await Table.UpdateAsync(item); //Delete from the local store
await SyncAsync(); //Send changes to the mobile service
return true;
}
public virtual async Task<bool> RemoveAsync(T item)
{
bool result = false;
try
{
await InitializeStoreAsync();
await Table.DeleteAsync(item); //Delete from the local store
await SyncAsync(); //Send changes to the mobile service
result = true;
}
catch (Exception e)
{
Logger.Instance.Track($"Unable to remove item {item.Id}:{e}");
}
return result;
}
//Note: do not call SyncAsync with ConfigureAwait(false) because when the authentication token expires,
//the thread running this method needs to open the Login UI.
//Also in the method which calls SyncAsync, do not use ConfigureAwait(false) before calling SyncAsync, because once ConfigureAwait(false) is used
//in the context of an async method, the rest of that method's code may also run on a background thread.
public virtual async Task<bool> SyncAsync()
{
if (!CrossConnectivity.Current.IsConnected)
{
Logger.Instance.Track("Unable to sync items, we are offline");
return false;
}
try
{
var client = ServiceLocator.Instance.Resolve<IAzureClient>()?.Client;
if (client == null)
{
Logger.Instance.Track("Unable to sync items, client is null");
return false;
}
//push changes on the sync context before pulling new items
await client.SyncContext.PushAsync();
await Table.PullAsync($"all{Identifier}", Table.CreateQuery());
}
catch (Exception ex)
{
Logger.Instance.Track("SyncAsync: Unable to push/pull items: " + ex.Message);
return false;
}
return true;
}
#endregion
}
}

View File

@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using MyDriving.DataObjects;
using MyDriving.DataStore.Abstractions;
using System.Threading.Tasks;
namespace MyDriving.DataStore.Azure.Stores
{
public class IOTHubStore : BaseStore<IOTHubData>, IHubIOTStore
{
public override string Identifier => "IOTHub";
public override Task<bool> SyncAsync()
{
return Task.FromResult(true);
}
object locker = new object();
public override Task<bool> InsertAsync(IOTHubData item)
{
lock(locker)
{
return base.InsertAsync(item);
}
}
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using MyDriving.DataObjects;
using MyDriving.DataStore.Abstractions;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
namespace MyDriving.DataStore.Azure.Stores
{
public class POIStore : BaseStore<POI>, IPOIStore
{
public async Task<IEnumerable<POI>> GetItemsAsync(string tripId)
{
//Always force refresh
await InitializeStoreAsync();
await SyncAsync();
return await Table.CreateQuery().Where(p => p.TripId == tripId).ToEnumerableAsync();
}
}
}

View File

@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using MyDriving.DataObjects;
using MyDriving.DataStore.Abstractions;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace MyDriving.DataStore.Azure.Stores
{
public class PhotoStore : BaseStore<Photo>, IPhotoStore
{
public override string Identifier => "Photo";
public override Task<bool> SyncAsync()
{
return Task.FromResult(true);
}
public Task<IEnumerable<Photo>> GetTripPhotos(string tripId)
{
return Table.Where(s => s.TripId == tripId).ToEnumerableAsync();
}
}
}

View File

@ -0,0 +1,80 @@
using Microsoft.WindowsAzure.MobileServices;
using MyDriving.AzureClient;
using MyDriving.DataObjects;
using MyDriving.DataStore.Abstractions;
using MyDriving.Utils;
using Plugin.Connectivity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyDriving.DataStore.Azure.Stores
{
public class TripPointStore : BaseStore<TripPoint>, ITripPointStore
{
public override string Identifier => "TripPoint";
public override async Task<bool> InsertAsync(TripPoint item)
{
await Table.InsertAsync(item);
return true;
}
public async Task<IEnumerable<TripPoint>> GetPointsForTripAsync(string id)
{
await InitializeStoreAsync();
//first look locally for points.
var points = await Table.Where(s => s.TripId == id).OrderBy(p => p.Sequence).ToEnumerableAsync();
if (points.Any())
return points;
if (!CrossConnectivity.Current.IsConnected)
{
Logger.Instance.Track("Unable to pull items, we are offline");
return new List<TripPoint>();
}
//if we don't have any points then we need to go up and pull them down.
try
{
//await SyncAsync();
var pullId = $"{id}";
await Table.PullAsync(pullId, Table.Where(s => s.TripId == id));
}
catch (Exception ex)
{
Logger.Instance.Track("TripPointStore: Unable to pull items: " + ex.Message);
}
return await Table.Where(s => s.TripId == id).OrderBy(p => p.Sequence).ToEnumerableAsync();
}
public override async Task<bool> SyncAsync()
{
if (!CrossConnectivity.Current.IsConnected)
{
Logger.Instance.Track("Unable to sync items, we are offline");
return false;
}
try
{
var client = ServiceLocator.Instance.Resolve<IAzureClient>()?.Client;
await client.SyncContext.PushAsync();
}
catch (Exception ex)
{
Logger.Instance.Track("TripPointStore SyncAsync: Unable to sync items: " + ex.Message);
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,105 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using System;
using MyDriving.DataObjects;
using MyDriving.DataStore.Abstractions;
using System.Threading.Tasks;
using MyDriving.Utils;
using System.Collections.Generic;
using System.Linq;
using MyDriving.AzureClient;
namespace MyDriving.DataStore.Azure.Stores
{
public class TripStore : BaseStore<Trip>, ITripStore
{
readonly IPhotoStore photoStore;
readonly ITripPointStore pointStore;
public TripStore()
{
photoStore = ServiceLocator.Instance.Resolve<IPhotoStore>();
pointStore = ServiceLocator.Instance.Resolve<ITripPointStore>();
}
public override string Identifier => "Trip";
public override async Task<bool> InsertAsync(Trip item)
{
return await base.InsertAsync(item);
}
public override async Task<IEnumerable<Trip>> GetItemsAsync(int skip = 0, int take = 100,
bool forceRefresh = false)
{
await InitializeStoreAsync();
if (forceRefresh)
{
await SyncAsync();
}
var items = await Table.Skip(skip).Take(take).OrderByDescending(s => s.RecordedTimeStamp).ToEnumerableAsync();
foreach (var item in items)
{
item.Photos = new List<Photo>();
var photos = await photoStore.GetTripPhotos(item.Id);
foreach (var photo in photos)
item.Photos.Add(photo);
}
return items;
}
public override async Task<Trip> GetItemAsync(string id)
{
var item = await base.GetItemAsync(id);
if (item.Photos == null)
item.Photos = new List<Photo>();
else
item.Photos.Clear();
var photos = await photoStore.GetTripPhotos(item.Id);
foreach (var photo in photos)
item.Photos.Add(photo);
item.Points = item.Points.OrderBy(p => p.Sequence).ToArray();
return item;
}
public override async Task<bool> RemoveAsync(Trip item)
{
bool result = false;
try
{
await InitializeStoreAsync();
var t = ServiceLocator.Instance.Resolve<IAzureClient>()?.Client?.GetSyncTable<TripPoint>();
var points = item.Points;
if (points == null || points.Count == 0)
{
points = new List<TripPoint>(await pointStore.GetPointsForTripAsync(item.Id));
}
foreach (var point in points)
{
await t.DeleteAsync(point);
}
await Table.DeleteAsync(item); //Delete from the local store
await SyncAsync(); //Send changes to the mobile service
result = true;
}
catch (Exception e)
{
Logger.Instance.Track($"Unable to remove item {item.Id}:{e}");
}
return result;
}
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
using MyDriving.DataObjects;
using MyDriving.DataStore.Abstractions;
using System.Linq;
namespace MyDriving.DataStore.Azure.Stores
{
public class UserStore : BaseStore<UserProfile>, IUserStore
{
public override string Identifier => "User";
public override async System.Threading.Tasks.Task<UserProfile> GetItemAsync(string id)
{
var users = await base.GetItemsAsync(0, 10, true);
return users.FirstOrDefault(s => s.UserId == id);
}
}
}