public QuestionPage() { this.InitializeComponent(); this.WhenActivated(d => { d(this.Bind(ViewModel, vm => vm.Question.Title, view => view.QuestionTitle.Text)); d(this.Bind(ViewModel, vm => vm.AnswersTitle, view => view.AnswersTitle.Text)); d(this.OneWayBind(ViewModel, vm => vm.Question, view => view.Question.ViewModel)); d(this.OneWayBind(ViewModel, vm => vm.Answers, view => view.Answers.ItemsSource)); d(ViewModel.Load.IsExecuting.BindTo(this, view => view.LoadingRing.IsActive)); d(ViewModel.Load.Execute().Subscribe()); var app = Locator.Current.GetService <IApplicationViewModel>(); app.OpenUri.RegisterHandler(ctx => { // TODO: Allow the user to specify whether to open in a real browser // or our pseudo-browser. if (!ctx.IsHandled) { SplitContent.IsPaneOpen = true; WebResults.Navigate(ctx.Input); ctx.SetOutput(Unit.Default); } }) .DisposeWith(d); }); }
public void Set <T>(WebResults <TokenResponceData <T> > webResults) { data = webResults.result; if (properties != null && properties.DataType == typeof(T)) { var prop = properties as TokenProperties <T>; prop.data = webResults.result.properties; } }
public override async Task <WebResults> SearchAsync(string query, WebResults.Type searchType = WebResults.Type.Song, int limit = 20, string pageToken = null) { switch (searchType) { default: var songResponse = await (pageToken == null ? _client.SearchAsync(Namespace.music, query, ContentSource.Catalog, SearchFilter.Tracks, maxItems: limit) : _client.SearchContinuationAsync(Namespace.music, pageToken)); var songResults = new WebResults { HasMore = songResponse.Tracks?.ContinuationToken != null, PageToken = songResponse.Tracks?.ContinuationToken, Songs = songResponse.Tracks?.Items?.Select(CreateSong).ToList() }; return(songResults); case WebResults.Type.Artist: var artistResponse = await (pageToken == null ? _client.SearchAsync(Namespace.music, query, ContentSource.Catalog, SearchFilter.Artists, maxItems: limit) : _client.SearchContinuationAsync(Namespace.music, pageToken)); var artistResults = new WebResults { HasMore = artistResponse.Artists?.ContinuationToken != null, PageToken = artistResponse.Artists?.ContinuationToken, Artists = artistResponse.Artists?.Items?.Select(CreateArtist).ToList() }; return(artistResults); case WebResults.Type.Album: var albumResponse = await (pageToken == null ? _client.SearchAsync(Namespace.music, query, ContentSource.Catalog, SearchFilter.Albums, maxItems: limit) : _client.SearchContinuationAsync(Namespace.music, pageToken)); var albumResults = new WebResults { HasMore = albumResponse.Albums?.ContinuationToken != null, PageToken = albumResponse.Albums?.ContinuationToken, Albums = albumResponse.Albums?.Items?.Select(CreateAlbum).Distinct(new WebAlbum.Comparer()).ToList() }; return(albumResults); } }
public async Task <WebResults> GetArtistTopSongsAsync(string artistToken, int limit = 20, string pageToken = null) { using (var response = await new SpotifyArtistTopTracksRequest(artistToken) .ToResponseAsync()) { if (!response.HasData) { throw new ProviderException(); } if (response.Data.HasError()) { throw new ProviderException(response.Data.ErrorResponse.Message); } var results = new WebResults { Songs = response.Data.Tracks.Select(CreateSong).Take(limit).ToList() }; return(results); } }
public async Task <WebResults> GetArtistAlbumsAsync(string artistToken, int limit = 50, string pageToken = null) { var response = await(pageToken == null ? _client.SubBrowseAsync(artistToken, ContentSource.Catalog, BrowseItemType.Artist, ExtraDetails.Albums, OrderBy.MostPopular, limit) : _client.SubBrowseContinuationAsync(artistToken, ContentSource.Catalog, BrowseItemType.Artist, ExtraDetails.Albums, pageToken)); var xboxArtist = response.Artists.Items.FirstOrDefault(); if (response.Error == null) { var results = new WebResults { HasMore = xboxArtist.Albums?.ContinuationToken != null, PageToken = xboxArtist.Albums?.ContinuationToken, Albums = xboxArtist.Albums?.Items?.Select(CreateAlbum).Distinct(new WebAlbum.Comparer()).ToList() }; return(results); } throw new ProviderException(response.Error.Message); }
public async Task <WebResults> GetArtistTopSongsAsync(string artistToken, int limit = 50, string pageToken = null) { var response = await(pageToken == null ? _client.SubBrowseAsync(artistToken, ContentSource.Catalog, BrowseItemType.Artist, ExtraDetails.TopTracks, maxItems: limit) : _client.SubBrowseContinuationAsync(artistToken, ContentSource.Catalog, BrowseItemType.Artist, ExtraDetails.TopTracks, pageToken)); var xboxArtist = response.Artists.Items.FirstOrDefault(); if (response.Error == null) { var results = new WebResults { HasMore = xboxArtist.TopTracks?.ContinuationToken != null, PageToken = xboxArtist.TopTracks?.ContinuationToken, Songs = xboxArtist.TopTracks?.Items?.Select(CreateSong).ToList() }; return(results); } throw new ProviderException(response.Error.Message); }
public void Set(WebResults <TokenResponceData> webResults) { data = webResults.result; }
/// <summary> /// Consumes a <see cref="BGSDKSettings"/> object updates it with the data found on service. /// </summary> /// <param name="settings">The settings to process ... these will be set as the active settings for the BGSDK API</param> /// <param name="identity">The identity of the user which will process the elements against the BGSDK service.</param> /// <returns></returns> public static IEnumerator SyncSettings(Action callback = null) { //First insure we have a fresh token based on secret if (string.IsNullOrEmpty(BGSDKSettings.current.appId.clientSecret) || string.IsNullOrEmpty(BGSDKSettings.current.appId.clientId)) { Debug.LogError("Failed to sync settings: you must populate the Client ID and Client Secret before you can sync settings."); yield return(null); } else { var settings = BGSDKSettings.current; var authenticated = false; WWWForm authForm = new WWWForm(); authForm.AddField("grant_type", "client_credentials"); authForm.AddField("client_id", BGSDKSettings.current.appId.clientId); authForm.AddField("client_secret", BGSDKSettings.current.appId.clientSecret); UnityWebRequest auth_www = UnityWebRequest.Post(BGSDKSettings.current.AuthenticationUri, authForm); var ao = auth_www.SendWebRequest(); while (!ao.isDone) { yield return(null); } if (!auth_www.isNetworkError && !auth_www.isHttpError) { string resultContent = auth_www.downloadHandler.text; if (BGSDKSettings.user == null) { BGSDKSettings.user = new Identity(); } BGSDKSettings.user.authentication = JsonUtility.FromJson <AuthenticationResponce>(resultContent); BGSDKSettings.user.authentication.not_before_policy = resultContent.Contains("not-before-policy:1"); BGSDKSettings.user.authentication.Create(); authenticated = true; } else { Debug.LogError((auth_www.isNetworkError ? "Error on authentication: Network Error." : "Error on authentication: HTTP Error.") + "\n" + auth_www.error); } if (authenticated) { /********************************************************************************** * First validate our model but skip the check on empty models ... this allows * the sync to be used to download the model from the service **********************************************************************************/ var message = string.Empty; if (ValidateSettingsModel(settings, out message, true) != ValidationStatus.Error) { foreach (var contract in settings.contracts) { contract.updatedFromServer = false; foreach (var token in contract.tokens) { token.UpdatedFromServer = false; } } //Good enough process the settings BGSDKSettings.current = settings; /********************************************************************************** * Next fetch a list of all contracts assoceated with the AppId recorded on * these settings **********************************************************************************/ UnityWebRequest wwwContract = UnityWebRequest.Get(settings.ContractUri); wwwContract.SetRequestHeader("Authorization", BGSDKSettings.user.authentication.token_type + " " + BGSDKSettings.user.authentication.access_token); var co = wwwContract.SendWebRequest(); while (!co.isDone) { yield return(null); } if (!wwwContract.isNetworkError && !wwwContract.isHttpError) { string resultContractContent = wwwContract.downloadHandler.text; var existingContracts = JsonUtility.FromJson <ListContractsResult>(Utilities.JSONArrayWrapper(resultContractContent)); /********************************************************************************** * Next for contract found try and match to a BGSDKContract object already recorded * in our settings, if none is found to match then create a new one and store it to * our settings. **********************************************************************************/ foreach (var contractData in existingContracts.result) { #region Update for data existing on the backend service //Try to match based on address ... this is the safest method var arkaneContract = settings.contracts.FirstOrDefault(p => p.data.address == contractData.address); if (arkaneContract != default(Engine.Contract)) { arkaneContract.data = contractData; if (arkaneContract.name != contractData.name) { arkaneContract.name = contractData.name; if (arkaneContract.tokens == null) { arkaneContract.tokens = new List <Engine.Token>(); } foreach (var token in arkaneContract.tokens) { token.name = arkaneContract.name + " : " + token.SystemName; } } arkaneContract.updatedFromServer = true; arkaneContract.updatedOn = DateTime.Now.ToBinary(); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(settings)); } else { //Try to match based on ID ... note if there are any contracts in the back end system then the first contract with an ID of 0 is likely to match arkaneContract = settings.contracts.FirstOrDefault(p => p.data.id == contractData.id); if (arkaneContract != default(Engine.Contract)) { arkaneContract.data = contractData; if (arkaneContract.name != contractData.name) { arkaneContract.name = contractData.name; if (arkaneContract.tokens == null) { arkaneContract.tokens = new List <Engine.Token>(); } foreach (var token in arkaneContract.tokens) { token.name = arkaneContract.name + " : " + token.SystemName; } } arkaneContract.updatedFromServer = true; arkaneContract.updatedOn = DateTime.Now.ToBinary(); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(settings)); } else { //Least reliable match method but should be tried all the same arkaneContract = settings.contracts.FirstOrDefault(p => p.data.name == contractData.name); if (arkaneContract != default(Engine.Contract)) { arkaneContract.data = contractData; if (arkaneContract.name != contractData.name) { arkaneContract.name = contractData.name; if (arkaneContract.tokens == null) { arkaneContract.tokens = new List <Engine.Token>(); } foreach (var token in arkaneContract.tokens) { token.name = arkaneContract.name + " : " + token.SystemName; } } arkaneContract.updatedFromServer = true; arkaneContract.updatedOn = DateTime.Now.ToBinary(); } else { /********************************************************************************** * At this point we have failed to match through all methods and so we should just * create a new BGSDKContract object and store it in our settings. **********************************************************************************/ arkaneContract = ScriptableObject.CreateInstance <Engine.Contract>(); arkaneContract.name = contractData.name; arkaneContract.data = contractData; arkaneContract.updatedFromServer = true; arkaneContract.updatedOn = DateTime.Now.ToBinary(); string path = AssetDatabase.GetAssetPath(Selection.activeObject); if (path == "") { path = "Assets"; } else if (Path.GetExtension(path) != "") { path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(Selection.activeObject)), ""); } string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath(path + "/" + contractData.name + ".asset"); AssetDatabase.CreateAsset(arkaneContract, assetPathAndName); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(settings)); settings.contracts.Add(arkaneContract); } } } #endregion /********************************************************************************** * Now that we have synced this contract to our settings object from the service * we need to look through all tokens on the service for this contract and either * sync them to the matching BGSDKToken object or create a new BGSDKToken object * to hold the data. **********************************************************************************/ #region Update token's for this contract that are on the backend service UnityWebRequest wwwToken = UnityWebRequest.Get(settings.GetTokenUri(arkaneContract)); wwwToken.SetRequestHeader("Authorization", BGSDKSettings.user.authentication.token_type + " " + BGSDKSettings.user.authentication.access_token); var to = wwwToken.SendWebRequest(); while (!to.isDone) { yield return(null); } if (!wwwToken.isNetworkError && !wwwToken.isHttpError) { string resultTokenContent = wwwToken.downloadHandler.text; var tokenResults = JsonUtility.FromJson <ListTokenTypesResult>(Utilities.JSONArrayWrapper(resultTokenContent)); Debug.Log("Found " + tokenResults.result.Count.ToString() + " tokens."); foreach (var tokenData in tokenResults.result) { Debug.Log("Found Token: " + tokenData.id); //Get the token so we can get the full data set for it UnityWebRequest wwwFullToken = UnityWebRequest.Get(settings.GetTokenUri(arkaneContract) + "/" + tokenData.id); wwwFullToken.SetRequestHeader("Authorization", BGSDKSettings.user.authentication.token_type + " " + BGSDKSettings.user.authentication.access_token); var ftd = wwwFullToken.SendWebRequest(); while (!ftd.isDone) { yield return(null); } WebResults <TokenResponceData> webResult = new WebResults <TokenResponceData>(wwwFullToken); if (!webResult.isNetworkError && !webResult.isHttpError) { var arkaneToken = arkaneContract.tokens.FirstOrDefault(p => p.Id == tokenData.id); if (arkaneToken != default(Engine.Token)) { arkaneToken.Set(webResult); if (arkaneToken.name != arkaneContract.name + " : " + arkaneToken.SystemName) { arkaneContract.name = arkaneContract.name + " : " + arkaneToken.SystemName; AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(settings)); } arkaneToken.UpdatedFromServer = true; arkaneToken.UpdatedOn = DateTime.Now.ToBinary(); } else { arkaneToken = arkaneContract.tokens.FirstOrDefault(p => p.SystemName == webResult.result.name && string.IsNullOrEmpty(p.Id)); if (arkaneToken != default(Engine.Token)) { arkaneToken.Set(webResult); if (arkaneToken.name != arkaneContract.name + " : " + arkaneToken.SystemName) { arkaneContract.name = arkaneContract.name + " : " + arkaneToken.SystemName; AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(settings)); } arkaneToken.UpdatedFromServer = true; arkaneToken.UpdatedOn = DateTime.Now.ToBinary(); } else { /********************************************************************************** * At this point we have failed to match the token to any existing BGSDKToken object * so we will create a new one and store it in our settings **********************************************************************************/ arkaneToken = ScriptableObject.CreateInstance <Engine.Token>(); arkaneToken.name = arkaneContract.name + " : " + webResult.result.name; arkaneToken.Set(webResult); arkaneToken.UpdatedFromServer = true; arkaneToken.UpdatedOn = DateTime.Now.ToBinary(); arkaneContract.tokens.Add(arkaneToken); string path = AssetDatabase.GetAssetPath(Selection.activeObject); if (path == "") { path = "Assets"; } else if (Path.GetExtension(path) != "") { path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(Selection.activeObject)), ""); } string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath(path + "/" + arkaneToken.name + ".asset"); AssetDatabase.CreateAsset(arkaneToken, assetPathAndName); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(settings)); } } } else { //TODO: handle fetch of token data error Debug.LogError("Failed to fetch full token data for Token Id = " + tokenData.id + " of contract Id = " + contractData.id); } } } else { //TODO: handle error getting token list Debug.LogError("Failed to fetch token list contract Id = " + contractData.id); } #endregion /********************************************************************************** * At this point we have synced all tokens for this contract from the service to * the settings object * * we now get a list of all the tokens that have not yet been synced for this contract * and sync them up to the service backend **********************************************************************************/ #region Add new tokens that are not yet on the backend service var newTokens = arkaneContract.tokens.Where(p => !p.UpdatedFromServer); foreach (var token in newTokens) { yield return(CreateTokenType(arkaneContract, token, (result) => { if (result.hasError) { Debug.LogError("Failed to create token [" + token.SystemName + "] for contract [" + arkaneContract.SystemName + "], error: " + result.httpCode + " message: " + result.message); } else { Debug.Log("Created token [" + token.SystemName + "] for contract [" + arkaneContract.SystemName + "]"); } })); } #endregion } /********************************************************************************** * At this point all contracts that already existed on the backend have been fully * synced. We now need to get all the contracts in our settings that have not yet * been synced and process them against the server. **********************************************************************************/ var newContracts = settings.contracts.Where(p => !p.updatedFromServer); foreach (var contract in newContracts) { DeployContractModel nContract = new DeployContractModel() { name = contract.data.name, description = contract.data.description }; var jsonString = JsonUtility.ToJson(nContract); UnityWebRequest wwwCreateContract = UnityWebRequest.Put(BGSDKSettings.current.ContractUri, jsonString); wwwCreateContract.method = UnityWebRequest.kHttpVerbPOST; wwwCreateContract.SetRequestHeader("Authorization", BGSDKSettings.user.authentication.token_type + " " + BGSDKSettings.user.authentication.access_token); wwwCreateContract.uploadHandler.contentType = "application/json;charset=UTF-8"; wwwCreateContract.SetRequestHeader("Content-Type", "application/json;charset=UTF-8"); var ccc = wwwCreateContract.SendWebRequest(); while (!ccc.isDone) { yield return(null); } if (!wwwCreateContract.isNetworkError && !wwwCreateContract.isHttpError) { string resultContent = wwwCreateContract.downloadHandler.text; var result = JsonUtility.FromJson <DataModel.ContractData>(resultContent); contract.data = result; contract.updatedFromServer = true; contract.updatedOn = DateTime.Now.ToBinary(); /********************************************************************************** * Finally get all the BGSDKToken objects for this contract and create them on the * server **********************************************************************************/ foreach (var token in contract.tokens) { yield return(CreateTokenType(contract, token, (r) => { if (r.hasError) { Debug.LogError("Failed to create token [" + token.SystemName + "] for contract [" + contract.SystemName + "], error: " + r.httpCode + " message: " + r.message); } else { Debug.Log("Created token [" + token.SystemName + "] for contract [" + contract.SystemName + "]"); } })); } } else { //TODO: handle error creating contract Debug.LogError("Failed to create contract: [Code: " + wwwCreateContract.responseCode + "] " + wwwCreateContract.error); } } } else { //TODO: notify the user that something went wrong while processing existing contracts. Debug.LogError("Failed to fetch the list of contracts: [Code: " + wwwContract.responseCode + "] " + wwwContract.error); } } else { //Some notable error occured in the validation step so report it to the end user Debug.LogError("Model validation failed:\n" + message); } } AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(settings)); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); if (callback != null) { callback.Invoke(); } } }