forked from rDrama/rDrama
Configure admin section and purchasing a ticket full flow
parent
cf7ee615e6
commit
469c39dca6
|
@ -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 *
|
|
@ -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,}
|
|
@ -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 } }
|
|
@ -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
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue