Esempio n. 1
0
        public static async Task <(Dictionary <string, WtmData> data, GetWtmCoinDataResult result)> GetWtmCoinData(IDictionary <string, double> coinHashList, bool interactive, StreamWriter logFile = null)
        {
            string statusBarText = "Downloading coin definitions from whattomine.com";

            ViewModel.Instance.StatusBarText = statusBarText + "...";

            int i = 0; int cnt = coinHashList.Count;
            var wtmRequestIntervalOld = ViewModel.Instance.WtmSettings.WtmRequestInterval;

            if (cnt > ViewModel.Instance.WtmSettings.DynamicRequestTrigger)
            {
                ViewModel.Instance.BypassUndo(() => {
                    if (ViewModel.Instance.WtmSettings.WtmRequestInterval < ViewModel.Instance.WtmSettings.DynamicRequestInterval)
                    {
                        ViewModel.Instance.WtmSettings.WtmRequestInterval = ViewModel.Instance.WtmSettings.DynamicRequestInterval;
                    }
                });
            }

            bool errorFlag            = false;
            bool continueFlag         = false;
            bool exitEarly            = false;

            CancellationTokenSource cancelSource = new CancellationTokenSource();
            CancellationToken       token        = cancelSource.Token;
            ProgressManager         pm           = null;


            if (interactive)
            {
                pm = new ProgressManager("Accessing whattomine.com...", cancelSource);
                pm.SetIndeterminate(true);
                pm.SetProgressMaxValue(cnt);
            }

            await RespectTimeLimit();

            var wtmLinks = await WhatToMine.GetWtmLinksFromJson(token).ConfigureAwait(false);

            if (token.IsCancellationRequested)
            {
                pm?.Close();
                return(null, GetWtmCoinDataResult.Fail);
            }
            if (wtmLinks == null)
            {
                string errorMessage = "Failed to get the list of available coins from whattomine.com.";
                if (interactive)
                {
                    pm?.Close();
                    MessageBox.Show(errorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                else
                {
                    if (logFile != null)
                    {
                        logFile.WriteLine(errorMessage);
                    }
                }
                return(null, GetWtmCoinDataResult.Fail);
            }
            if (interactive && pm != null)
            {
                pm.SetIndeterminate(false);
                pm.SetText("Downloading " + i + " of " + cnt);
                pm.SetProgressValue(0);
            }

            var    wtmDataDict                = new Dictionary <string, WtmData>();
            string currentJsonStr             = string.Empty;
            string currentCoinHtml            = string.Empty;
            GetWtmCoinDataResult methodResult = GetWtmCoinDataResult.OK;

            foreach (var coin in coinHashList)
            {
                continueFlag = false;
                List <string> httpResults = new List <string>();
                WtmLinks      entry;
                wtmLinks.TryGetValue(coin.Key, out entry);
                if (entry == null)
                {
                    string errorMessage = $"{coin.Key} has not been found among coins at http://whattomine.com/calculators. Execution aborted.";
                    errorFlag = true; methodResult = GetWtmCoinDataResult.CoinNotFound;
                    if (interactive)
                    {
                        Helpers.ShowErrorMessage(errorMessage);
                    }
                    else
                    {
                        if (logFile != null)
                        {
                            logFile.WriteLine(errorMessage);
                        }
                    }
                    break;
                }

                //Check whattomine coin status
                if (!string.Equals(entry.Status, "Active", StringComparison.InvariantCultureIgnoreCase))
                {
                    MessageBoxResult response = MessageBoxResult.OK;
                    string           message  = $"The status of {coin.Key} is reported as \"{entry.Status}\" by whattomine.com.";
                    if (interactive)
                    {
                        response = MessageBox.Show(message, "Coin is not active", MessageBoxButton.OKCancel, MessageBoxImage.Warning);
                    }
                    else
                    {
                        logFile.WriteLine(message);
                    }
                    if (interactive && response == MessageBoxResult.Cancel)
                    {
                        errorFlag = true;
                        break;
                    }
                    continue;
                }

                await RespectTimeLimit();

                try
                {
                    var response = await WtmHttpClient.GetAsync(entry.JsonLink + "?hr=" + coin.Value.ToString(CultureInfo.InvariantCulture), token).ConfigureAwait(false);

                    var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                    if (result != null && result.Contains("errors"))
                    {
                        var wtmErrorDict = JsonConverter.ConvertFromJson <Dictionary <string, object> >(result);
                        if (wtmErrorDict != null)
                        {
                            object errorObj = null;
                            wtmErrorDict.TryGetValue("errors", out errorObj);
                            var errorList = errorObj as ArrayList;
                            if (errorList != null)
                            {
                                string errorMessage = string.Join(". ", errorList.ToArray());
                                if (errorMessage != null)
                                {
                                    throw new Exception(errorMessage);
                                }
                            }
                        }
                    }

                    response.EnsureSuccessStatusCode();
                    httpResults.Add(result);
                }
                catch (Exception e)
                {
                    if (interactive && e.Message == "A task was canceled.")
                    {
                        errorFlag = true; methodResult = GetWtmCoinDataResult.Fail;
                    }
                    else
                    {
                        string errorMessage = $"Failed to download {coin.Key} definition from whattomine.com.";
                        //continueFlag = true;
                        errorFlag    = true;
                        methodResult = GetWtmCoinDataResult.Fail;
                        if (interactive)
                        {
                            Helpers.ShowErrorMessage(errorMessage + "\n\n" + e.Message);
                        }
                        else
                        {
                            if (logFile != null)
                            {
                                logFile.WriteLine(errorMessage);
                            }
                        }
                    }
                }

                //if (continueFlag)
                //    continue;

                if (errorFlag || httpResults == null)
                {
                    break;
                }

                // Interpret JSON
                currentJsonStr = httpResults[0];
                Dictionary <string, string> json = new Dictionary <string, string>();
                json = JsonConverter.ConvertFromJson <Dictionary <string, string> >(currentJsonStr);

                if (json == null)
                {
                    string errorMessage = $"Failed to interpret {coin.Key} definition from whattomine.com.";
                    errorFlag = true; methodResult = GetWtmCoinDataResult.Fail;
                    if (interactive)
                    {
                        Helpers.ShowErrorMessage(errorMessage);
                    }
                    else
                    {
                        if (logFile != null)
                        {
                            logFile.WriteLine(errorMessage);
                        }
                    }
                    break;
                }
                else
                {
                    var defaultHashrate = coin.Value;
                    wtmDataDict.Add(coin.Key, new WtmData {
                        DefaultHashrate = defaultHashrate, Json = json
                    });
                }

                if (pm != null && !pm.IsAlive)
                {
                    exitEarly = true;
                    break;
                }

                i++;
                if (interactive && pm != null)
                {
                    pm.SetText("Downloaded " + i + " of " + cnt);
                    pm.SetProgressValue(i);
                }
                else
                {
                    ViewModel.Instance.StatusBarText = statusBarText + ": " + i + " of " + cnt;
                }
            }

            ViewModel.Instance.BypassUndo(() => ViewModel.Instance.WtmSettings.WtmRequestInterval = wtmRequestIntervalOld);
            ViewModel.Instance.UpdateNextJobStatus();

            if (!exitEarly && interactive)
            {
                pm?.Close();
            }
            if (errorFlag || exitEarly)
            {
                return(null, methodResult);
            }
            if (!interactive && (logFile != null))
            {
                var noun = wtmDataDict.Count == 1 ? "coin" : "coins";
                logFile.WriteLine($"The list of {wtmDataDict.Count} whattomine.com {noun} has been downloaded.");
            }
            return(wtmDataDict, GetWtmCoinDataResult.OK);
        }