Example #1
0
        public async Task <ActionResult> TipUser(int id, int?amount, int?tx)
        {
            using (var db = new ZapContext())
            {
                var receiver = await db.Users
                               .Include(usr => usr.Funds)
                               .Include(usr => usr.EarningEvents)
                               .Include(usr => usr.Settings)
                               .Where(u => u.Id == id).FirstOrDefaultAsync();

                if (receiver == null)
                {
                    Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    return(Json(new { Result = "Failure", Message = "User not found." }));
                }

                if (tx == null)
                {
                    var userId = User.Identity.GetUserId();
                    if (userId == null)
                    {
                        return(Json(new { Result = "Failure", Message = "User not found." }));
                    }

                    var user = await db.Users
                               .Include(usr => usr.Funds)
                               .Include(usr => usr.SpendingEvents)
                               .Where(u => u.AppId == userId).FirstOrDefaultAsync();

                    // Ensure user has the funds available.
                    if (user.Funds.Balance < amount)
                    {
                        Response.StatusCode = (int)HttpStatusCode.Forbidden;
                        return(Json(new { Result = "Failure", Message = "Not enough funds." }));
                    }

                    // All requirements are met - make payment
                    user.Funds.Balance     -= amount.Value;
                    receiver.Funds.Balance += amount.Value;

                    // Add Earning Event

                    var ea = new EarningEvent()
                    {
                        Amount     = amount.Value,
                        OriginType = 2,
                        TimeStamp  = DateTime.UtcNow,
                        Type       = 0,
                    };

                    receiver.EarningEvents.Add(ea);

                    var spendingEvent = new SpendingEvent()
                    {
                        Amount    = amount.Value,
                        TimeStamp = DateTime.UtcNow,
                    };

                    user.SpendingEvents.Add(spendingEvent);

                    // Notify receiver
                    var alert = new UserAlert()
                    {
                        TimeStamp = DateTime.Now,
                        Title     = "You received a tip!",
                        Content   = "From: <a href='" + @Url.Action(actionName: "Index", controllerName: "User", routeValues: new { username = user.Name }) + "'>" + user.Name + "</a><br/> Amount: " + amount.ToString() + " Satoshi.",
                        IsDeleted = false,
                        IsRead    = false,
                        To        = receiver,
                    };

                    receiver.Alerts.Add(alert);
                    await db.SaveChangesAsync();

                    try
                    {
                        if (receiver.Settings == null)
                        {
                            receiver.Settings = new UserSettings();
                        }

                        if (receiver.Settings.NotifyOnReceivedTip)
                        {
                            string receiverEmail = UserManager.FindById(receiver.AppId).Email;
                            MailingService.Send(user: "******",
                                                message: new UserEmailModel()
                            {
                                Subject     = "You received a tip!",
                                Body        = "From: " + user.Name + "<br/> Amount: " + amount.ToString() + " Satoshi.<br/><br/><a href='http://www.zapread.com'>zapread.com</a>",
                                Destination = receiverEmail,
                                Email       = "",
                                Name        = "ZapRead.com Notify"
                            });
                        }
                    }
                    catch (Exception e)
                    {
                        // Send an email.
                        MailingService.Send(new UserEmailModel()
                        {
                            Destination = "*****@*****.**",
                            Body        = " Exception: " + e.Message + "\r\n Stack: " + e.StackTrace + "\r\n user: "******"",
                            Name        = "zapread.com Exception",
                            Subject     = "Send NotifyOnReceivedTip error.",
                        });
                    }

                    return(Json(new { Result = "Success" }));
                }
                else
                {
                    // Anonymous tip

                    var vtx = await db.LightningTransactions.FirstOrDefaultAsync(txn => txn.Id == tx);

                    if (vtx == null || vtx.IsSpent == true)
                    {
                        Response.StatusCode = (int)HttpStatusCode.Forbidden;
                        return(Json(new { Result = "Failure", Message = "Transaction not found" }));
                    }

                    vtx.IsSpent = true;

                    receiver.Funds.Balance += amount.Value;// vtx.Amount;//amount;

                    // Notify receiver
                    var alert = new UserAlert()
                    {
                        TimeStamp = DateTime.Now,
                        Title     = "You received a tip!",
                        Content   = "From: anonymous <br/> Amount: " + amount.ToString() + " Satoshi.",
                        IsDeleted = false,
                        IsRead    = false,
                        To        = receiver,
                    };

                    receiver.Alerts.Add(alert);
                    await db.SaveChangesAsync();

                    if (receiver.Settings == null)
                    {
                        receiver.Settings = new UserSettings();
                    }

                    if (receiver.Settings.NotifyOnReceivedTip)
                    {
                        string receiverEmail = UserManager.FindById(receiver.AppId).Email;
                        MailingService.Send(user: "******",
                                            message: new UserEmailModel()
                        {
                            Subject     = "You received a tip!",
                            Body        = "From: anonymous <br/> Amount: " + amount.ToString() + " Satoshi.<br/><br/><a href='http://www.zapread.com'>zapread.com</a>",
                            Destination = receiverEmail,
                            Email       = "",
                            Name        = "ZapRead.com Notify"
                        });
                    }
                    return(Json(new { Result = "Success" }));
                }
            }
        }
Example #2
0
        public async Task <ActionResult> Post(Vote v)
        {
            if (!ModelState.IsValid)
            {
                return(Json(new { result = "error", message = "Invalid" }));
            }

            if (v.a < 1)
            {
                return(Json(new { result = "error", message = "Invalid" }));
            }

            var userId = User.Identity.GetUserId();

            // if userId is null, then it is anonymous

            using (var db = new ZapContext())
            {
                var post = db.Posts
                           .Include("VotesUp")
                           .Include("VotesDown")
                           .Include(p => p.UserId)
                           .Include(p => p.UserId.Funds)
                           .FirstOrDefault(p => p.PostId == v.Id);

                if (post == null)
                {
                    return(Json(new { result = "error", message = "Invalid Post" }));
                }

                Models.User user = null;

                if (userId == null)// Anonymous vote
                {
                    // Check if vote tx has been claimed
                    if (v.tx != -1337) //debugging secret
                    {
                        var vtx = db.LightningTransactions.FirstOrDefault(tx => tx.Id == v.tx);

                        if (vtx == null || vtx.IsSpent == true)
                        {
                            return(Json(new { result = "error", message = "No transaction to vote with" }));
                        }

                        vtx.IsSpent = true;
                        await db.SaveChangesAsync();
                    }
                }
                else
                {
                    user = db.Users
                           .Include(usr => usr.Funds)
                           .Include(usr => usr.EarningEvents)
                           .Include(usr => usr.SpendingEvents)
                           .FirstOrDefault(u => u.AppId == userId);

                    if (user == null)
                    {
                        return(Json(new { result = "error", message = "Invalid User" }));
                    }

                    if (user.Funds.Balance < v.a)
                    {
                        return(Json(new { result = "error", message = "Insufficient Funds." }));
                    }

                    user.Funds.Balance -= v.a;
                }

                var spendingEvent = new SpendingEvent()
                {
                    Amount    = v.a,
                    Post      = post,
                    TimeStamp = DateTime.UtcNow,
                };

                double userBalance = 0.0;
                if (user != null)
                {
                    userBalance = user.Funds.Balance;
                    user.SpendingEvents.Add(spendingEvent);
                }

                if (v.d == 1)
                {
                    // Voted up
                    if (user != null && post.VotesUp.Contains(user))
                    {
                        // Already voted - remove upvote?
                        //post.VotesUp.Remove(user);
                        //user.PostVotesUp.Remove(post);
                        //post.Score = post.VotesUp.Count() - post.VotesDown.Count();
                        //return Json(new { result = "success", message = "Already Voted", delta = 0, score = post.Score, balance = user.Funds.Balance });
                    }
                    else if (user != null)
                    {
                        post.VotesUp.Add(user);
                        user.PostVotesUp.Add(post);
                    }

                    //post.VotesDown.Remove(user);
                    //user.PostVotesDown.Remove(post);
                    //post.Score = post.VotesUp.Count() - post.VotesDown.Count();
                    post.Score += v.a;

                    // Record and assign earnings
                    // Related to post owner
                    post.TotalEarned += 0.6 * v.a;

                    var ea = new EarningEvent()
                    {
                        Amount     = 0.6 * v.a,
                        OriginType = 0,
                        TimeStamp  = DateTime.UtcNow,
                        Type       = 0,
                    };

                    var webratio = 0.1;
                    var comratio = 0.1;

                    //post.EarningEvents.Add(ea);

                    var owner = post.UserId;
                    if (owner != null)
                    {
                        owner.Reputation += v.a;
                        owner.EarningEvents.Add(ea);
                        owner.TotalEarned += 0.6 * v.a;

                        if (owner.Funds == null)
                        {
                            owner.Funds = new UserFunds()
                            {
                                Balance = 0.6 * v.a, TotalEarned = 0.6 * v.a
                            };
                        }
                        else
                        {
                            owner.Funds.Balance += 0.6 * v.a;
                        }
                    }

                    var postGroup = post.Group;
                    if (postGroup != null)
                    {
                        postGroup.TotalEarnedToDistribute += 0.2 * v.a;
                    }
                    else
                    {
                        // not in group - send to community
                        comratio += 0.2;
                    }

                    var website = db.ZapreadGlobals.FirstOrDefault(i => i.Id == 1);

                    if (website != null)
                    {
                        // Will be distributed to all users
                        website.CommunityEarnedToDistribute += comratio * v.a;

                        // And to the website
                        website.ZapReadTotalEarned   += webratio * v.a;
                        website.ZapReadEarnedBalance += webratio * v.a;
                    }

                    try
                    {
                        await db.SaveChangesAsync();
                    }
                    catch (Exception)
                    {
                        return(Json(new { result = "error", message = "Error" }));
                    }

                    return(Json(new { result = "success", delta = 1, score = post.Score, balance = userBalance, scoreStr = post.Score.ToAbbrString() }));
                }
                else
                {
                    // Voted down
                    if (user != null && post.VotesDown.Contains(user))
                    {
                        //post.VotesDown.Remove(user);
                        //user.PostVotesDown.Remove(post);
                        //post.Score = post.VotesUp.Count() - post.VotesDown.Count();
                        //return Json(new { result = "success", message = "Already Voted", delta = 0, score = post.Score, balance = user.Funds.Balance });
                    }
                    else if (user != null)
                    {
                        post.VotesDown.Add(user);
                        user.PostVotesDown.Add(post);
                    }
                    //post.VotesUp.Remove(user);
                    //user.PostVotesUp.Remove(post);

                    post.Score = post.Score - v.a;// post.VotesUp.Count() - post.VotesDown.Count();

                    // Record and assign earnings
                    // Related to post owner
                    var webratio = 0.1;
                    var comratio = 0.1;

                    var owner = post.UserId;
                    if (owner != null)
                    {
                        owner.Reputation -= v.a;
                    }

                    var postGroup = post.Group;
                    if (postGroup != null)
                    {
                        postGroup.TotalEarnedToDistribute += 0.8 * v.a;
                    }
                    else
                    {
                        comratio += 0.8;
                    }

                    var website = db.ZapreadGlobals.FirstOrDefault(i => i.Id == 1);

                    if (website != null)
                    {
                        // Will be distributed to all users
                        website.CommunityEarnedToDistribute += comratio * v.a;

                        // And to the website
                        website.ZapReadTotalEarned   += webratio * v.a;
                        website.ZapReadEarnedBalance += webratio * v.a;
                    }

                    await db.SaveChangesAsync();

                    return(Json(new { result = "success", delta = -1, score = post.Score, balance = userBalance, scoreStr = post.Score.ToAbbrString() }));
                }
            }
            // All paths have returned
        }