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 .saves import *
|
||||||
from .views import *
|
from .views import *
|
||||||
from .notifications 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))
|
original_username = deferred(Column(String))
|
||||||
referred_by = Column(Integer, ForeignKey("users.id"))
|
referred_by = Column(Integer, ForeignKey("users.id"))
|
||||||
subs_created = Column(Integer, default=0)
|
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)
|
badges = relationship("Badge", viewonly=True)
|
||||||
subscriptions = relationship("Subscription", 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.strip() for i in self.custom_filter_list.split('\n')] if self.custom_filter_list else []
|
||||||
l = [i for i in l if i]
|
l = [i for i in l if i]
|
||||||
return l
|
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.alerts import *
|
||||||
from files.helpers.get import *
|
from files.helpers.get import *
|
||||||
from files.helpers.const import *
|
from files.helpers.const import *
|
||||||
|
from files.helpers.lottery import *
|
||||||
|
|
||||||
@app.post("/lottery/start")
|
|
||||||
@auth_required
|
|
||||||
def lottery_start(v):
|
|
||||||
# Save changes
|
|
||||||
g.db.commit()
|
|
||||||
|
|
||||||
return {"message": "Lottershe started."}
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/lottery/end")
|
@app.post("/lottery/end")
|
||||||
@auth_required
|
@auth_required
|
||||||
def lottery_end(v):
|
def lottery_end(v):
|
||||||
# Save changes
|
end_lottery_session(g)
|
||||||
g.db.commit()
|
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")
|
@app.post("/lottery/buy")
|
||||||
@limiter.limit("1/second;30/minute;200/hour;1000/day")
|
@limiter.limit("1/second;30/minute;200/hour;1000/day")
|
||||||
@auth_required
|
@auth_required
|
||||||
def lottery_buy(v):
|
def lottery_buy(v):
|
||||||
if v.coins < 12:
|
success, message, lottery_stats = purchase_lottery_ticket(g, v)
|
||||||
return {"error": "Lottershe tickets cost 12 dramacoins each."}, 400
|
|
||||||
|
|
||||||
# Charge user for ticket
|
if success:
|
||||||
v.coins -= 12
|
return {"message": message, "stats": {"user": v.lottery_stats, "lottery": lottery_stats}}
|
||||||
|
else:
|
||||||
# Check for active lottery
|
return {"error": message, "stats": {"user": v.lottery_stats, "lottery": lottery_stats}}
|
||||||
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}}
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/lottery/stats")
|
@app.get("/lottery/active")
|
||||||
@limiter.limit("1/second;30/minute;200/hour;1000/day")
|
@limiter.limit("1/second;30/minute;200/hour;1000/day")
|
||||||
@auth_required
|
@auth_required
|
||||||
def lottery_stats(v):
|
def lottery_active(v):
|
||||||
return {"message": {"sessionEnds": 0, "prize": 0, "ticketsSoldSession": 0, "ticketsSoldTotal": 0}}
|
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>
|
||||||
<div class="lottery-modal--stats">
|
<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">
|
||||||
<div class="lottery-modal--stat-keys">
|
<div class="lottery-modal--stat-keys">
|
||||||
<div>Grand Prize</div>
|
<div>Grand Prize</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
CREATE TABLE public.lotteries (
|
CREATE TABLE public.lotteries (
|
||||||
id integer NOT NULL,
|
id SERIAL PRIMARY KEY,
|
||||||
is_active boolean DEFAULT false NOT NULL,
|
is_active boolean DEFAULT false NOT NULL,
|
||||||
ends_at timestamptz NOT NULL,
|
ends_at integer NOT NULL,
|
||||||
prize integer DEFAULT 0 NOT NULL,
|
prize integer DEFAULT 0 NOT NULL,
|
||||||
tickets_sold integer DEFAULT 0 NOT NULL
|
tickets_sold integer DEFAULT 0 NOT NULL
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue