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);
            });
        }
Пример #2
0
        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;
            }
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
 public void Set(WebResults <TokenResponceData> webResults)
 {
     data = webResults.result;
 }
Пример #8
0
        /// <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();
                }
            }
        }