Example #1
0
        //Url must be StoryStats/:StoryID/Action/values
        public StoryStatsController()
        {
            var auth = new UserAuth(); //DI this

            _userID = auth.UserID;
            _user   = auth.User;

            _dbContext        = new AdventureTimeDbContext( );
            _dbContext.userID = auth.User;

            //validate and set route params
            var r       = HttpContext.Current.Request.RequestContext.RouteData;
            var storyID = r.Values["storyID"];

            if (storyID == null ||
                !int.TryParse((string)storyID, out _storyID) ||
                (_story = _dbContext.Stories.Find(_storyID)) == null)
            {
                throw new HttpRequestException("Invalid Route. Route must contain storyID");
            }

            var pageID = r.Values["pageID"];

            //if page in route then validate page
            if (pageID != null &&
                ((!int.TryParse((string)pageID, out _pageID) ||
                  (_page = _dbContext.Pages.Find(_pageID)) == null) ||
                 (_page.Story.ID != _storyID)))
            {
                throw new HttpRequestException("Invalid Route. pageID is Invalid");
                //pageID is invalid or does not match story
            }

            //to enforce: story stats must be created when story is created 1:1
            _storyStats = _dbContext.StoryStats.Single(t => t.Story.ID == _storyID);
            _stats      = _dbContext.UserStoryStats.SingleOrDefault(t => t.UserID == _userID && t.Story.ID == _storyID);
            if (_stats == default(UserStoryStats))
            {
                _stats = new UserStoryStats {
                    UserID = _userID, Story = _story
                };
                _dbContext.UserStoryStats.Add(_stats);
                _dbContext.SaveChanges();
            }
        }
Example #2
0
        private void SeedTables(IdentityUser rootUser)
        {
            //create db context
            using (var dbContext = new AdventureTimeDbContext())
            {
                dbContext.userID           = rootUser;
                dbContext.AutoSeedMetadata = false;

                using (var dbContextTransaction = dbContext.Database.BeginTransaction())
                {
                    try
                    {
                        Console.WriteLine("Seeding Users...");
                        //create users
                        var userDtos = new XmlParser("Users.xml")
                                       .ParseElements(t => new UserDTO()
                        {
                            UserName = (string)t.XPathSelectElement("UserName"),
                            Password = (string)t.XPathSelectElement("Password"),
                            Email    = (string)t.XPathSelectElement("Email")
                        }).ToList();
                        var users   = new List <IdentityUser>();
                        var manager = new UserManager <IdentityUser>(new UserStore <IdentityUser>());
                        foreach (var u in userDtos)
                        {
                            if (manager.FindByName(u.UserName) == null)
                            {
                                manager.Create(new IdentityUser()
                                {
                                    UserName = u.UserName, Email = u.Email
                                }, u.Password);
                                users.Add(manager.FindByName(u.UserName));
                            }
                        }

                        Console.WriteLine("Seeding Tags...");
                        //create tags
                        var tags = new XmlParser("Tags.xml")
                                   .ParseElements(t => new Tag()
                        {
                            Text       = (string)t.XPathSelectElement("Name"),
                            IsApproved = true
                        })
                                   .AddMetaData().ToList();

                        dbContext.Tags.AddRange(tags);
                        dbContext.SaveChanges();

                        //save tags
                        var savedTags     = dbContext.Tags.ToList();
                        var savedTagCount = savedTags.Count();


                        Console.WriteLine("Seeding Stories...");
                        //create stories
                        var stories = new XmlParser("Stories.xml")
                                      .ParseElements(t => new Story()
                        {
                            Title    = (string)t.XPathSelectElement("Title"),
                            Summary  = (string)t.XPathSelectElement("Summary"),
                            Settings = (string)t.XPathSelectElement("Settings"),
                            IsLocked = false
                        })
                                      .AddMetaData().ToList();
                        stories.ForEach(t =>
                        {
                            var rep = rand.Next(2, 6);
                            t.Tags  = new Collection <Tag>();
                            for (var ix = 0; ix < rep; ix++)
                            {
                                t.Tags.Add(savedTags[rand.Next(0, savedTagCount - 1)]);
                            }

                            //trim summary,settings
                            t.Summary  = t.Summary.Substring(0, Math.Min(500, t.Summary.Length));
                            t.Settings = t.Settings.Substring(0, Math.Min(250, t.Settings.Length));
                        });

                        //save stories
                        dbContext.Stories.AddRange(stories);
                        dbContext.SaveChanges();

                        //feature stories to seed pages for
                        const int someStoriesCount = 4;
                        var       someStories      = dbContext.Stories.Take(someStoriesCount).ToArray();

                        // create pages
                        //depends on stories
                        Console.WriteLine("Seeding Pages...");
                        var pages = new XmlParser("Pages.xml")
                                    .ParseElements(t => new Page()
                        {
                            Text       = (string)t.XPathSelectElement("Text"),
                            PageNumber = (int)t.XPathSelectElement("PageNumber"),
                            IsEnding   = false   // (bool)t.XPathSelectElement("IsEnding")
                        })
                                    .AddMetaData()
                                    .ToList();

                        var pageCount         = pages.Count();
                        var pagesPerSomeStory = pageCount / someStoriesCount;
                        var prevStoryIx       = -1;
                        var endingChance      = 0.00;
                        for (var pIx = 0; pIx < pageCount; pIx++)
                        {
                            var page    = pages.ElementAt(pIx);
                            var storyIx = pIx / pagesPerSomeStory;
                            page.Story = someStories[storyIx];

                            if (storyIx != prevStoryIx)
                            {
                                endingChance = 0.00;
                                someStories[storyIx].FirstPage = page;
                            }
                            else
                            {
                                //chance of hitting ending increases towards end of story
                                endingChance += (.25 / (double)pagesPerSomeStory);
                                page.IsEnding = rand.NextDouble() < endingChance * endingChance;
                            }
                            prevStoryIx = storyIx;

                            page.Text = page.Text.Substring(0, Math.Min(3000, page.Text.Length));
                        }
                        //save pages
                        dbContext.Pages.AddRange(pages);
                        dbContext.SaveChanges();

                        var savedPages = dbContext.Pages.Select(t => t);


                        //create actions in each story
                        Console.WriteLine("Seeding Actions...");
                        var actions = new XmlParser("Actions.xml")
                                      .ParseElements(t => new Action()
                        {
                            Text = (string)t.XPathSelectElement("Text")
                        })
                                      .AddMetaData().ToList();

                        //assign actions pages, story, etc.
                        var actionsCount    = actions.Count();
                        var someStoryIx     = 0;
                        var actionsPerStory = actionsCount / someStoriesCount;
                        var rem             = actionsCount % someStoriesCount;
                        foreach (var group in savedPages.GroupBy(t => t.Story))
                        {
                            var story       = group.Key;
                            var someActions = actions.GetRange(
                                actionsPerStory * someStoryIx,
                                actionsPerStory + ((someStoryIx == someStoriesCount - 1) ? rem : 0)).ToList();
                            someActions.ForEach(a =>
                            {
                                a.Story = story;
                                a.Text  = a.Text.Substring(0, Math.Min(500, a.Text.Length));
                            });

                            var storyPages     = group.Select(t => t).OrderBy(t => t.PageNumber).ToList();
                            var pagesPerStory  = storyPages.Count();
                            var actionsPerPage = actionsPerStory / pagesPerStory;

                            var actionsPerThisStory = someActions.Count;
                            for (var ix = 0; ix < actionsPerThisStory; ix++)
                            {
                                var action     = someActions[ix];
                                var childPage  = storyPages[(((ix + 1) * 2) / actionsPerPage) % pagesPerStory];
                                var parentPage = storyPages[(ix / actionsPerPage)];
                                if (parentPage.IsEnding)
                                {
                                    //no action
                                }
                                else
                                {
                                    //assign action to pages
                                    action.ParentID = parentPage.ID;
                                    action.ChildID  = childPage.ID;
                                }
                            }

                            someStoryIx++;
                        }

                        //remove actions that did not get parent assigned
                        actions = actions.Where(t => t.ParentID != null).ToList();
                        dbContext.Actions.AddRange(actions);
                        dbContext.SaveChanges();
                        dbContextTransaction.Commit();


                        Console.WriteLine("Seeding Playing Stats...");
                        //Seed User Stats, User Story Stats
                        var usersCount = users.Count();
                        List <UserStoryStats>  userStoryStats   = new List <UserStoryStats>();
                        List <StoryStats>      storyStats       = new List <StoryStats>();
                        List <UserStoryEnding> userStoryEndings = new List <UserStoryEnding>();

                        for (var i = 0; i < someStories.Length; i++)
                        {
                            var story        = someStories[i];
                            var endings      = story.Pages.Where(t => t.IsEnding);
                            var endingsCount = endings.Count();

                            var thisUserStoryStats = new List <UserStoryStats>();

                            for (var u = 0; u < usersCount; u++)
                            {
                                var hasPlayed = rand.NextDouble() < .4;
                                if (!hasPlayed)
                                {
                                    continue;
                                }

                                var user = users[u];

                                var userStat = new UserStoryStats
                                {
                                    IsLike      = rand.NextDouble() < .2,
                                    IsFavorite  = rand.NextDouble() < .1,
                                    Minutes     = rand.Next(3, 10),
                                    Plays       = rand.Next(1, 3),
                                    Completions = rand.Next(1, 4),
                                    Pages       = rand.Next(1, 200),
                                    Actions     = rand.Next(2, 200),
                                    UserID      = user.Id,
                                    Story       = story
                                };


                                if (endingsCount > 0)
                                {
                                    for (var c = 0; c < userStat.Completions; c++)
                                    {
                                        var page = endings.ElementAt(rand.Next(0, endingsCount));
                                        userStoryEndings.Add(new UserStoryEnding()
                                        {
                                            UserID = user.Id,
                                            Story  = story,
                                            Page   = page
                                        });
                                    }
                                }
                                thisUserStoryStats.Add(userStat);
                            }

                            var storyStat = new StoryStats
                            {
                                Story       = story,
                                Pages       = story.Pages.Count(),
                                Actions     = story.Actions.Count(),
                                Likes       = thisUserStoryStats.Count(t => t.IsLike),
                                Favorites   = thisUserStoryStats.Count(t => t.IsFavorite),
                                Plays       = thisUserStoryStats.Sum(t => t.Plays),
                                Completions = thisUserStoryStats.Sum(t => t.Completions),
                                Views       = thisUserStoryStats.Count(),
                                Endings     = endingsCount
                            };

                            userStoryStats.AddRange(thisUserStoryStats);
                            storyStats.Add(storyStat);
                        }

                        dbContext.UserStoryEndings.AddRange(userStoryEndings);
                        dbContext.StoryStats.AddRange(storyStats);
                        dbContext.UserStoryStats.AddRange(userStoryStats);
                        dbContext.SaveChanges();

                        //add story stats for remaining stories
                        var emptyStats = new List <StoryStats>();
                        var someIds    = new HashSet <int>(someStories.Select(t => t.ID));
                        dbContext.Stories.Where(s => !someIds.Contains(s.ID))
                        .ForEach(t => {
                            var stat = new StoryStats()
                            {
                                Story = t
                            };
                            emptyStats.Add(stat);
                        });
                        dbContext.StoryStats.AddRange(emptyStats);

                        dbContext.SaveChanges();
                    }
                    catch (Exception)
                    {
                        dbContextTransaction.Rollback();
                        throw;
                    }
                } //end transaction
            }     //end db context
        }