public static UserActivity From(TalkRating rating, Talk talk, User user)
 {
     return new UserActivity
     {
         TalkId = rating.TalkId,
         Time = DateTime.UtcNow,
         TalkAuthor = talk.Author,
         Content = string.Format("\"{0}\" was thumbed-up ({1}) at #tccc19 http://speakr.cc/#{2}",
             talk.Title,
             talk.Ranking > 0 ? "+" + talk.Ranking.ToString() : talk.Ranking.ToString(),
             talk.Id)
     };
 }
        public Talk Rate(TalkRating talkRating)
        {
            using (var session = RavenInstance.Db.OpenSession())
            {
                var userSessionId = this.GetUserSessionId();
                if (userSessionId == null)
                {
                    throw new InvalidOperationException("No user session Id.");
                }

                var user = session
                    .Query<User>()
                    .Customize(x => x.WaitForNonStaleResultsAsOfNow(TimeSpan.FromSeconds(2)))
                    .First(u => u.SessionId == userSessionId);

                // Update the talk and up/down vote info.
                var talk = session.Load<Talk>(talkRating.TalkId);
                var existingRating = user.Ratings.FirstOrDefault(r => r.TalkId == talkRating.TalkId);
                var changeAmount = 1;
                if (existingRating != null)
                {
                    if (existingRating.UpVote != talkRating.UpVote)
                    {
                        changeAmount = 2;
                        if (existingRating.UpVote)
                        {
                            talk.UpVotes -= 1;
                        }
                        else
                        {
                            talk.DownVotes -= 1;
                        }

                        existingRating.UpVote = talkRating.UpVote;
                    }
                    else
                    {
                        // The user didn't change his existing rating.
                        // Return without changing anything.
                        talk.YouDownVoted = !existingRating.UpVote;
                        talk.YouUpVoted = existingRating.UpVote;
                        return talk;
                    }
                }
                else
                {
                    user.Ratings.Add(talkRating);
                }

                talk.Ranking += changeAmount * (talkRating.UpVote ? 1 : -1);
                if (talkRating.UpVote)
                {
                    talk.UpVotes += 1;
                    talk.YouUpVoted = true;
                }
                else
                {
                    talk.DownVotes += 1;
                    talk.YouDownVoted = true;
                }

                user.LastActivity = DateTime.Now;
                session.Store(user);

                if (existingRating == null && talkRating.UpVote)
                {
                    var activity = UserActivity.From(talkRating, talk, user);
                    session.Store(activity);
                }

                session.SaveChanges();
                return talk;
            }
        }