Configure admin section and purchasing a ticket full flow

remotes/1693045480750635534/spooky-22
Outrun Colors, LLC 2022-05-28 22:33:44 -05:00
parent cf7ee615e6
commit 469c39dca6
7 changed files with 193 additions and 30 deletions

View File

@ -18,4 +18,5 @@ from .sub_block import *
from .saves import *
from .views import *
from .notifications import *
from .follows import *
from .follows import *
from .lottery import *

View File

@ -0,0 +1,31 @@
import time
from sqlalchemy import *
from files.__main__ import Base
from files.helpers.lazy import lazy
from files.helpers.const import *
class Lottery(Base):
__tablename__ = "lotteries"
id = Column(Integer, primary_key=True)
is_active = Column(Boolean, default=False)
ends_at = Column(Integer)
prize = Column(Integer, default=0)
tickets_sold = Column(Integer, default=0)
@property
@lazy
def timeleft(self):
if not self.is_active:
return 0
epoch_time = int(time.time())
remaining_time = self.ends_at - epoch_time
return 0 if remaining_time < 0 else remaining_time
@property
@lazy
def stats(self):
return {"active": self.is_active, "timeLeft": self.timeleft, "prize": self.prize, "ticketsSoldThisSession": self.tickets_sold,}

View File

@ -126,6 +126,9 @@ class User(Base):
original_username = deferred(Column(String))
referred_by = Column(Integer, ForeignKey("users.id"))
subs_created = Column(Integer, default=0)
currently_held_lottery_tickets = Column(Integer, default=0)
total_held_lottery_tickets = Column(Integer, default=0)
total_lottery_winnings = Column(Integer, default=0)
badges = relationship("Badge", viewonly=True)
subscriptions = relationship("Subscription", viewonly=True)
@ -655,3 +658,8 @@ class User(Base):
l = [i.strip() for i in self.custom_filter_list.split('\n')] if self.custom_filter_list else []
l = [i for i in l if i]
return l
@property
@lazy
def lottery_stats(self):
return { "winnings": self.total_lottery_winnings, "ticketsHeld": { "current": self.currently_held_lottery_tickets , "total": self.total_held_lottery_tickets } }

View File

@ -0,0 +1,97 @@
import time
from sqlalchemy import *
from files.helpers.wrappers import *
LOTTERY_TICKET_COST = 12
# The amount of dramacoins permanently removed from the economy to reduce expected value
SINK_RATE = 3
# The amount of dramacoins the lottery founders receive
ROYALTY_RATE = 1
# The account in which royalties are to be deposited
ROYALTY_ACCOUNT_ID = 9
# The account in which the prize is held to be accessed by anyone
MANAGER_ACCOUNT_ID = 3
def get_most_recent_lottery(g):
lotteries = g.db.query(Lottery).order_by(Lottery.id.desc())
count = 0
mostRecent = None
for lottery in lotteries:
if count == 0:
mostRecent = lottery
count += 1
return mostRecent
def end_lottery_session(g):
# Check that a current session exists
most_recent_lottery = get_most_recent_lottery(g)
if (most_recent_lottery is None or not most_recent_lottery.is_active):
return
# Calculate players and odds
# Payout to winner
# Send DM to all involved
most_recent_lottery.is_active = False
# Save changes
g.db.commit()
def start_new_lottery_session(g):
# Wrap up current session
end_lottery_session(g)
# Create new session
lottery = Lottery()
epoch_time = int(time.time())
one_week_from_now = epoch_time + 60 * 60 * 24 * 7
lottery.ends_at = one_week_from_now
lottery.is_active = True
# Save changes
g.db.add(lottery)
g.db.commit()
def purchase_lottery_ticket(g, v):
if (v.coins < LOTTERY_TICKET_COST):
return False, f'Lottery tickets cost {LOTTERY_TICKET_COST} dramacoins each.', None
most_recent_lottery = get_most_recent_lottery(g)
if (most_recent_lottery is None or not most_recent_lottery.is_active):
return False, "There is no active lottery.", None
# Charge the user and update the lottery
v.coins -= LOTTERY_TICKET_COST
v.currently_held_lottery_tickets += 1
v.total_held_lottery_tickets += 1
net_ticket_value = LOTTERY_TICKET_COST - SINK_RATE - ROYALTY_RATE
most_recent_lottery.prize += net_ticket_value
most_recent_lottery.tickets_sold += 1
# Pass the holdings to the lottery manager
manager = g.db.query(User).get(MANAGER_ACCOUNT_ID)
manager.coins += net_ticket_value
# Pay royalties
beneficiary = g.db.query(User).get(ROYALTY_ACCOUNT_ID)
beneficiary.coins += ROYALTY_RATE
# Save changes
g.db.commit()
return True, 'Successfully purchased a lottery ticket!', most_recent_lottery.stats

View File

@ -3,47 +3,42 @@ from files.helpers.wrappers import *
from files.helpers.alerts import *
from files.helpers.get import *
from files.helpers.const import *
@app.post("/lottery/start")
@auth_required
def lottery_start(v):
# Save changes
g.db.commit()
return {"message": "Lottershe started."}
from files.helpers.lottery import *
@app.post("/lottery/end")
@auth_required
def lottery_end(v):
# Save changes
g.db.commit()
end_lottery_session(g)
return {"message": "Lottery ended."}
return {"message": "Lottershe ended."}
@app.post("/lottery/start")
@auth_required
def lottery_start(v):
start_new_lottery_session(g)
return {"message": "Lottery started."}
@app.post("/lottery/buy")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@auth_required
def lottery_buy(v):
if v.coins < 12:
return {"error": "Lottershe tickets cost 12 dramacoins each."}, 400
success, message, lottery_stats = purchase_lottery_ticket(g, v)
# Charge user for ticket
v.coins -= 12
# Check for active lottery
pass
# Save changes
g.db.commit()
return {"message": "Lottershe ticket purchased!", "stats": {"sessionEnds": 0, "prize": 0, "ticketsSoldSession": 0, "ticketsSoldTotal": 0, "ticketsHeldSession": 0, "ticketsHeldTotal": 0, "totalWinnings": 0}}
if success:
return {"message": message, "stats": {"user": v.lottery_stats, "lottery": lottery_stats}}
else:
return {"error": message, "stats": {"user": v.lottery_stats, "lottery": lottery_stats}}
@app.get("/lottery/stats")
@app.get("/lottery/active")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@auth_required
def lottery_stats(v):
return {"message": {"sessionEnds": 0, "prize": 0, "ticketsSoldSession": 0, "ticketsSoldTotal": 0}}
def lottery_active(v):
most_recent_lottery = get_most_recent_lottery(g)
if most_recent_lottery is None or not most_recent_lottery.is_active:
return {"message": "There is no active lottery."}
return {"message": most_recent_lottery.stats}

View File

@ -25,6 +25,37 @@
/>
</div>
<div class="lottery-modal--stats">
{% if v.admin_level > 2 %}
<div class="lottery-modal--stat" style="position: relative; padding-top: 1rem;">
<i
class="fas fa-broom"
style="
position: absolute;
top: -8px;
right: -8px;
font-size: 20px;
"
>
</i>
<button
type="button"
class="btn btn-danger"
id="endLotterySession"
onclick="endLotterySession()"
>
End Current Session
</button>
<button
type="button"
class="btn btn-success"
id="startLotterySession"
onclick="startLotterySession()"
>
Start New Session
</button>
</div>
{% endif %}
<div class="lottery-modal--stat">
<div class="lottery-modal--stat-keys">
<div>Grand Prize</div>

View File

@ -1,7 +1,7 @@
CREATE TABLE public.lotteries (
id integer NOT NULL,
id SERIAL PRIMARY KEY,
is_active boolean DEFAULT false NOT NULL,
ends_at timestamptz NOT NULL,
ends_at integer NOT NULL,
prize integer DEFAULT 0 NOT NULL,
tickets_sold integer DEFAULT 0 NOT NULL
);