Example #1
0
        public ActivityCommand(ServiceFacade serviceFacade,
                               ConfigureUserSite configureUserSite,
                               DataGenerator.Activity activityDataGenerator,
                               DataGenerator.DateTime dateTimeDataGenerator,
                               ActivityService activityService)
            : base(serviceFacade, configureUserSite)
        {
            _activityDataGenerator = activityDataGenerator
                                     ?? throw new ArgumentNullException(nameof(activityDataGenerator));
            _dateTimeDataGenerator = dateTimeDataGenerator
                                     ?? throw new ArgumentNullException(nameof(dateTimeDataGenerator));
            _activityService = activityService
                               ?? throw new ArgumentNullException(nameof(activityService));

            _facade.App.Command("activity", _ =>
            {
                _.Description = "Create, read, update, or delete activity";
                _.HelpOption("-?|-h|--help");

                var createRandomOption = _.Option("-er|--enterrandom <count>",
                                                  "Enter <count> random activity items",
                                                  CommandOptionType.SingleValue);

                var displayStatusOption = _.Option("-q|--quiet",
                                                   "Suppress status while entering activity items",
                                                   CommandOptionType.NoValue);

                var challengeStatusOption = _.Option("-c|--challenge",
                                                     "Include random challenge tasks when entering random activity items",
                                                     CommandOptionType.NoValue);

                var challengePercentOption = _.Option("-cp|--challengepercent <percentage>",
                                                      "Specify what percentage of activities should be challenges. Defaults to 30.",
                                                      CommandOptionType.SingleValue);

                var codePercentOption = _.Option("-scp|--secretcodepercent <percentage>",
                                                 "Specify what percentage of non-challenge activities should be secret codes. Defaults to 30.",
                                                 CommandOptionType.SingleValue);

                _.OnExecute(async() =>
                {
                    bool quiet = displayStatusOption.HasValue() &&
                                 displayStatusOption.Value().Equals("on", StringComparison.CurrentCultureIgnoreCase);

                    bool challenges = challengeStatusOption.HasValue() &&
                                      challengeStatusOption.Value().Equals("on", StringComparison.CurrentCultureIgnoreCase);

                    int challengePercent = challenges ? 30 : 0;
                    if (challenges && challengePercentOption.HasValue())
                    {
                        if (!(int.TryParse(challengePercentOption.Value(), out challengePercent) &&
                              challengePercent >= 0 &&
                              challengePercent < 101))
                        {
                            throw new ArgumentException("Error: <percentage> must be a number between 0 and 100.");
                        }
                    }

                    int codePercent = 30;
                    if (codePercentOption.HasValue())
                    {
                        if (!(int.TryParse(codePercentOption.Value(), out codePercent) &&
                              codePercent >= 0 &&
                              codePercent < 101))
                        {
                            throw new ArgumentException("Error: <percentage> must be a number between 0 and 100.");
                        }
                    }

                    if (createRandomOption.HasValue())
                    {
                        if (!int.TryParse(createRandomOption.Value(), out int howMany))
                        {
                            throw new ArgumentException("Error: <count> must be a number random activity items to enter.");
                        }
                        return(await EnterActivity(howMany, challengePercent, codePercent, quiet));
                    }
                    else
                    {
                        _.ShowHelp();
                        return(2);
                    }
                });
            }, throwOnUnexpectedArg: true);

            async Task <int> EnterActivity(int howMany,
                                           int challengePercent,
                                           int codePercent,
                                           bool quiet)
            {
                int inserted = 0;
                var issues   = new List <string>();

                var activities
                    = await _activityDataGenerator.Generate(Site, howMany, challengePercent, codePercent, quiet);

                if (!quiet)
                {
                    Console.Write($"Inserting {howMany} activity items... ");
                }

                ProgressBar progress = quiet ? null : new ProgressBar();

                try
                {
                    foreach (var activity in activities)
                    {
                        _dateTimeDataGenerator.SetRandom(Site, activity.User);
                        try
                        {
                            await _configureUserSite.Lookup(activity.User.Id);

                            _activityService.ClearCachedUserContext();
                            switch (activity.ActivityType)
                            {
                            case DataGenerator.ActivityType.SecretCode:
                                await _activityService
                                .LogSecretCodeAsync(activity.User.Id, activity.SecretCode);

                                break;

                            case DataGenerator.ActivityType.ChallengeTasks:
                                await _activityService
                                .UpdateChallengeTasksAsync(activity.ChallengeId, activity.ChallengeTasks);

                                break;

                            default:
                            case DataGenerator.ActivityType.Default:
                                await _activityService
                                .LogActivityAsync(activity.User.Id, activity.ActivityAmount);

                                break;
                            }
                            inserted++;
                        }
                        catch (GraException gex)
                        {
                            switch (activity.ActivityType)
                            {
                            case DataGenerator.ActivityType.ChallengeTasks:
                                issues.Add($"Problem logging challenge tasks for {activity.User.Id}: {gex.Message}");
                                break;

                            case DataGenerator.ActivityType.SecretCode:
                                issues.Add($"Problem logging code {activity.SecretCode} for {activity.User.Id}: {gex.Message}");
                                break;

                            default:
                            case DataGenerator.ActivityType.Default:
                                issues.Add($"Problem logging {activity.ActivityAmount} for {activity.User.Id}: {gex.Message}");
                                break;
                            }
                        }
                        if (progress != null)
                        {
                            progress.Report((double)inserted / howMany);
                        }
                    }
                }
                finally
                {
                    if (progress != null)
                    {
                        progress.Dispose();
                    }
                }

                Console.WriteLine($"Inserted {inserted} random activity items in {Site.Name}.");

                if (issues.Count > 0)
                {
                    Console.WriteLine("Some issues were encountered:");
                    foreach (string issue in issues)
                    {
                        Console.WriteLine($"- {issue}");
                    }
                }

                return(inserted == howMany ? 0 : 1);
            }
        }
        private async Task <int> CreateUsers(int howMany, bool household, bool quiet)
        {
            int created = 0;

            int[]   familyOptions = { 1, 2, 3, 4, 5, FamilyRandomIndicator, GroupRandomIndicator };
            float[] familyWeights = { 0.25F, 0.35F, 0.21F, 0.10F, 0.04F, 0.047F, 0.003F };

            var issues = new List <string>();

            // make the participants
            var users = await _userDataGenerator.Generate(Site.Id, howMany);

            var minDateTime = DateTime.MaxValue;
            var maxDateTime = DateTime.MinValue;

            if (!quiet)
            {
                Console.Write($"Inserting {howMany} users... ");
            }

            ProgressBar progress = quiet ? null : new ProgressBar();

            try
            {
                var rand                 = new Bogus.Randomizer();
                int familyMembers        = 0;
                Domain.Model.User parent = null;

                // insert the participants
                foreach (var user in users)
                {
                    bool currentUserParent = false;

                    // set an appropriate random date and time for insertion
                    var setDateTime = _dateTimeDataGenerator.SetRandom(Site);

                    if (setDateTime < minDateTime)
                    {
                        minDateTime = setDateTime;
                    }
                    if (setDateTime > maxDateTime)
                    {
                        maxDateTime = setDateTime;
                    }

                    if (familyMembers > 0)
                    {
                        // we are processing family members
                        user.User.LastName = parent.LastName;
                        if (rand.Int(1, 100) > 5)
                        {
                            user.User.Username = null;
                        }

                        // insert the family member
                        try
                        {
                            await _facade
                            .UserService
                            .AddHouseholdMemberAsync(parent.Id, user.User);

                            created++;
                        }
                        catch (GraException gex)
                        {
                            issues.Add($"Household username: {user.User.Username} - {gex.Message}");
                        }
                        familyMembers--;
                    }
                    else
                    {
                        // not processing family members, should this person be a head of household?
                        if (household && rand.Int(1, 100) <= 31)
                        {
                            currentUserParent = true;

                            familyMembers = rand.WeightedRandom <int>(familyOptions, familyWeights);
                            if (familyMembers == FamilyRandomIndicator)
                            {
                                familyMembers = rand.Int(6, 10);
                            }
                            else if (familyMembers == GroupRandomIndicator)
                            {
                                familyMembers = rand.Int(11, 100);
                            }
                        }

                        // insert the created user
                        try
                        {
                            var inserted = await _facade
                                           .UserService
                                           .RegisterUserAsync(user.User, user.Password);

                            if (currentUserParent)
                            {
                                parent = inserted;
                            }
                            created++;
                        }
                        catch (Exception ex)
                        {
                            issues.Add($"Username: {user.User.Username} - {ex.Message}");
                        }
                    }

                    if (progress != null)
                    {
                        progress.Report((double)created / howMany);
                    }
                }
            }
            finally
            {
                if (progress != null)
                {
                    progress.Dispose();
                }
            }

            Console.WriteLine($"Created {created} random users in {Site.Name}.");
            Console.WriteLine($"Users registered between {minDateTime} and {maxDateTime}.");

            if (issues.Count > 0)
            {
                Console.WriteLine("Some issues were encountered:");
                foreach (string issue in issues)
                {
                    Console.WriteLine($"- {issue}");
                }
            }

            await DisplayUserCount();

            return(howMany == created ? 0 : 1);
        }