forked from rDrama/rDrama
Fix conflicts
commit
195c6936ee
|
@ -19,3 +19,4 @@ 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,32 @@
|
||||||
|
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)
|
||||||
|
winner_id = Column(Integer, ForeignKey("users.id"))
|
||||||
|
|
||||||
|
@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,}
|
|
@ -127,6 +127,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)
|
||||||
|
@ -259,13 +262,6 @@ class User(Base):
|
||||||
def age(self):
|
def age(self):
|
||||||
return int(time.time()) - self.created_utc
|
return int(time.time()) - self.created_utc
|
||||||
|
|
||||||
@property
|
|
||||||
@lazy
|
|
||||||
def ban_reason_link(self):
|
|
||||||
if self.ban_reason:
|
|
||||||
if self.ban_reason.startswith("/post/"): return self.ban_reason.split(None, 1)[0]
|
|
||||||
if self.ban_reason.startswith("/comment/"): return self.ban_reason.split(None, 1)[0] + "?context=8#context"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@lazy
|
@lazy
|
||||||
def alts_unique(self):
|
def alts_unique(self):
|
||||||
|
@ -656,3 +652,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 } }
|
|
@ -173,6 +173,7 @@ if SITE in {'rdrama.net','devrama.xyz'}:
|
||||||
"6": "947236351445725204",
|
"6": "947236351445725204",
|
||||||
"7": "886781932430565418",
|
"7": "886781932430565418",
|
||||||
}
|
}
|
||||||
|
|
||||||
elif SITE == "pcmemes.net":
|
elif SITE == "pcmemes.net":
|
||||||
HOLE_COST = 10000
|
HOLE_COST = 10000
|
||||||
NOTIFICATIONS_ID = 1046
|
NOTIFICATIONS_ID = 1046
|
||||||
|
@ -1013,3 +1014,19 @@ procoins_li = (0,2500,5000,10000,25000,50000,125000,250000)
|
||||||
linefeeds_regex = re.compile("([^\n])\n([^\n])", flags=re.A)
|
linefeeds_regex = re.compile("([^\n])\n([^\n])", flags=re.A)
|
||||||
|
|
||||||
def make_name(*args, **kwargs): return request.base_url
|
def make_name(*args, **kwargs): return request.base_url
|
||||||
|
|
||||||
|
# Lottery
|
||||||
|
if SITE_NAME == 'rDrama':
|
||||||
|
LOTTERY_ENABLED = True
|
||||||
|
LOTTERY_TICKET_COST = 12
|
||||||
|
LOTTERY_SINK_RATE = 3
|
||||||
|
LOTTERY_ROYALTY_RATE = 1
|
||||||
|
LOTTERY_ROYALTY_ACCOUNT_ID = 8239 # (McCoxmaul)
|
||||||
|
LOTTERY_MANAGER_ACCOUNT_ID = 11651 # (Lottershe)
|
||||||
|
else:
|
||||||
|
LOTTERY_ENABLED = False
|
||||||
|
LOTTERY_TICKET_COST = 0
|
||||||
|
LOTTERY_SINK_RATE = 0
|
||||||
|
LOTTERY_ROYALTY_RATE = 0
|
||||||
|
LOTTERY_ROYALTY_ACCOUNT_ID = 0
|
||||||
|
LOTTERY_MANAGER_ACCOUNT_ID = 0
|
|
@ -50,4 +50,9 @@ def timestamp(timestamp):
|
||||||
|
|
||||||
@app.context_processor
|
@app.context_processor
|
||||||
def inject_constants():
|
def inject_constants():
|
||||||
return {"environ":environ, "SITE":SITE, "SITE_NAME":SITE_NAME, "SITE_FULL":SITE_FULL, "AUTOJANNY_ID":AUTOJANNY_ID, "NOTIFICATIONS_ID":NOTIFICATIONS_ID, "PUSHER_ID":PUSHER_ID, "CC":CC, "CC_TITLE":CC_TITLE, "listdir":listdir, "MOOSE_ID":MOOSE_ID, "AEVANN_ID":AEVANN_ID, "PIZZASHILL_ID":PIZZASHILL_ID, "config":app.config.get, "DEFAULT_COLOR":DEFAULT_COLOR, "COLORS":COLORS, "ADMIGGERS":ADMIGGERS, "datetime":datetime, "time":time}
|
return {"environ":environ, "SITE":SITE, "SITE_NAME":SITE_NAME, "SITE_FULL":SITE_FULL,
|
||||||
|
"AUTOJANNY_ID":AUTOJANNY_ID, "NOTIFICATIONS_ID":NOTIFICATIONS_ID, "PUSHER_ID":PUSHER_ID,
|
||||||
|
"CC":CC, "CC_TITLE":CC_TITLE, "listdir":listdir, "MOOSE_ID":MOOSE_ID, "AEVANN_ID":AEVANN_ID,
|
||||||
|
"PIZZASHILL_ID":PIZZASHILL_ID, "config":app.config.get, "DEFAULT_COLOR":DEFAULT_COLOR,
|
||||||
|
"COLORS":COLORS, "ADMIGGERS":ADMIGGERS, "datetime":datetime, "time":time,
|
||||||
|
"LOTTERY_ENABLED": LOTTERY_ENABLED}
|
|
@ -0,0 +1,114 @@
|
||||||
|
import time
|
||||||
|
from random import choice
|
||||||
|
from sqlalchemy import *
|
||||||
|
from files.helpers.alerts import *
|
||||||
|
from files.helpers.wrappers import *
|
||||||
|
from flask import g
|
||||||
|
from .const import *
|
||||||
|
|
||||||
|
|
||||||
|
def get_active_lottery():
|
||||||
|
return g.db.query(Lottery).order_by(Lottery.id.desc()).filter(Lottery.is_active).one_or_none()
|
||||||
|
|
||||||
|
|
||||||
|
def get_users_participating_in_lottery():
|
||||||
|
return g.db.query(User).filter(User.currently_held_lottery_tickets > 0).all()
|
||||||
|
|
||||||
|
|
||||||
|
def get_active_lottery_stats():
|
||||||
|
active_lottery = get_active_lottery()
|
||||||
|
participating_users = get_users_participating_in_lottery()
|
||||||
|
|
||||||
|
return None if active_lottery is None else active_lottery.stats, len(participating_users)
|
||||||
|
|
||||||
|
|
||||||
|
def end_lottery_session():
|
||||||
|
active_lottery = get_active_lottery()
|
||||||
|
|
||||||
|
if (active_lottery is None):
|
||||||
|
return False, "There is no active lottery."
|
||||||
|
|
||||||
|
participating_users = get_users_participating_in_lottery()
|
||||||
|
raffle = []
|
||||||
|
for user in participating_users:
|
||||||
|
for _ in range(user.currently_held_lottery_tickets):
|
||||||
|
raffle.append(user.id)
|
||||||
|
|
||||||
|
winner = choice(raffle)
|
||||||
|
active_lottery.winner_id = winner
|
||||||
|
winning_user = next(filter(lambda x: x.id == winner, participating_users))
|
||||||
|
winning_user.coins += active_lottery.prize
|
||||||
|
winning_user.total_lottery_winnings += active_lottery.prize
|
||||||
|
|
||||||
|
for user in participating_users:
|
||||||
|
chance_to_win = user.currently_held_lottery_tickets / len(raffle) * 100
|
||||||
|
notification_text = f'You won {active_lottery.prize} dramacoins in the lottery! Congratulations!\nOdds of winning: {chance_to_win}%' if user.id == winner else "You did not win the lottery. Better luck next time!\nOdds of winning: {chance_to_win}%"
|
||||||
|
send_repeatable_notification(user.id, notification_text)
|
||||||
|
user.currently_held_lottery_tickets = 0
|
||||||
|
|
||||||
|
active_lottery.is_active = False
|
||||||
|
|
||||||
|
manager = g.db.query(User).get(LOTTERY_MANAGER_ACCOUNT_ID)
|
||||||
|
manager.coins -= active_lottery.prize
|
||||||
|
|
||||||
|
g.db.commit()
|
||||||
|
|
||||||
|
return True, f'{winning_user.username} won {active_lottery.prize} dramacoins!'
|
||||||
|
|
||||||
|
|
||||||
|
def start_new_lottery_session():
|
||||||
|
end_lottery_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
|
||||||
|
|
||||||
|
g.db.add(lottery)
|
||||||
|
g.db.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def purchase_lottery_ticket(v):
|
||||||
|
if (v.coins < LOTTERY_TICKET_COST):
|
||||||
|
return False, f'Lottery tickets cost {LOTTERY_TICKET_COST} dramacoins each.'
|
||||||
|
|
||||||
|
most_recent_lottery = get_active_lottery()
|
||||||
|
if (most_recent_lottery is None):
|
||||||
|
return False, "There is no active lottery."
|
||||||
|
|
||||||
|
v.coins -= LOTTERY_TICKET_COST
|
||||||
|
v.currently_held_lottery_tickets += 1
|
||||||
|
v.total_held_lottery_tickets += 1
|
||||||
|
|
||||||
|
net_ticket_value = LOTTERY_TICKET_COST - LOTTERY_SINK_RATE - LOTTERY_ROYALTY_RATE
|
||||||
|
most_recent_lottery.prize += net_ticket_value
|
||||||
|
most_recent_lottery.tickets_sold += 1
|
||||||
|
|
||||||
|
grant_lottery_proceeds_to_manager(net_ticket_value)
|
||||||
|
|
||||||
|
beneficiary = g.db.query(User).get(LOTTERY_ROYALTY_ACCOUNT_ID)
|
||||||
|
beneficiary.coins += LOTTERY_ROYALTY_RATE
|
||||||
|
|
||||||
|
g.db.commit()
|
||||||
|
|
||||||
|
return True, 'Successfully purchased a lottery ticket!'
|
||||||
|
|
||||||
|
def grant_lottery_proceeds_to_manager(amount):
|
||||||
|
manager = g.db.query(User).get(LOTTERY_MANAGER_ACCOUNT_ID)
|
||||||
|
manager.coins += amount
|
||||||
|
|
||||||
|
def grant_lottery_tickets_to_user(v, amount):
|
||||||
|
active_lottery = get_active_lottery()
|
||||||
|
prize_value = amount * LOTTERY_TICKET_COST
|
||||||
|
|
||||||
|
if active_lottery:
|
||||||
|
v.currently_held_lottery_tickets += amount
|
||||||
|
v.total_held_lottery_tickets += amount
|
||||||
|
|
||||||
|
active_lottery.prize += prize_value
|
||||||
|
active_lottery.tickets_sold += amount
|
||||||
|
|
||||||
|
grant_lottery_proceeds_to_manager(amount)
|
||||||
|
|
||||||
|
g.db.commit()
|
|
@ -247,7 +247,7 @@ def sanitize(sanitized, alert=False, comment=False, edit=False):
|
||||||
for rd in ["://reddit.com", "://new.reddit.com", "://www.reddit.com", "://redd.it", "://libredd.it", "://teddit.net"]:
|
for rd in ["://reddit.com", "://new.reddit.com", "://www.reddit.com", "://redd.it", "://libredd.it", "://teddit.net"]:
|
||||||
sanitized = sanitized.replace(rd, "://old.reddit.com")
|
sanitized = sanitized.replace(rd, "://old.reddit.com")
|
||||||
|
|
||||||
sanitized = normalize_url(sanitized)
|
sanitized = sanitize_url(sanitized)
|
||||||
|
|
||||||
sanitized = sanitized.replace('&','&')
|
sanitized = sanitized.replace('&','&')
|
||||||
|
|
||||||
|
@ -377,7 +377,8 @@ def filter_emojis_only(title, edit=False, graceful=False):
|
||||||
if len(title) > 1500 and not graceful: abort(400)
|
if len(title) > 1500 and not graceful: abort(400)
|
||||||
else: return title
|
else: return title
|
||||||
|
|
||||||
def normalize_url(url):
|
def sanitize_url(url):
|
||||||
|
# NB: Used in this file to sanitize all URLs in bulk text.
|
||||||
url = url.replace("nitter.net", "twitter.com") \
|
url = url.replace("nitter.net", "twitter.com") \
|
||||||
.replace("old.reddit.com/gallery", "reddit.com/gallery") \
|
.replace("old.reddit.com/gallery", "reddit.com/gallery") \
|
||||||
.replace("https://youtu.be/", "https://youtube.com/watch?v=") \
|
.replace("https://youtu.be/", "https://youtube.com/watch?v=") \
|
||||||
|
@ -392,6 +393,11 @@ def normalize_url(url):
|
||||||
.replace("https://www.instagram", "https://instagram") \
|
.replace("https://www.instagram", "https://instagram") \
|
||||||
.replace("https://www.tiktok", "https://tiktok")
|
.replace("https://www.tiktok", "https://tiktok")
|
||||||
|
|
||||||
|
return url
|
||||||
|
|
||||||
|
def normalize_url(url):
|
||||||
|
url = sanitize_url(url)
|
||||||
|
|
||||||
if "/i.imgur.com/" in url:
|
if "/i.imgur.com/" in url:
|
||||||
url = url.replace(".png", ".webp").replace(".jpg", ".webp").replace(".jpeg", ".webp")
|
url = url.replace(".png", ".webp").replace(".jpg", ".webp").replace(".jpeg", ".webp")
|
||||||
elif "/media.giphy.com/" in url or "/c.tenor.com/" in url:
|
elif "/media.giphy.com/" in url or "/c.tenor.com/" in url:
|
||||||
|
|
|
@ -1,22 +1,26 @@
|
||||||
import random
|
from random import randint
|
||||||
|
from math import floor
|
||||||
|
from files.helpers.const import *
|
||||||
|
from files.helpers.lottery import *
|
||||||
|
|
||||||
special_min = 100
|
special_min = 100
|
||||||
special_max = 200
|
special_max = 200
|
||||||
standard_min = 10
|
standard_min = 10
|
||||||
standard_max = 100
|
standard_max = 100
|
||||||
|
lotterizer_rate = 33
|
||||||
|
|
||||||
def check_for_treasure(in_text, from_comment):
|
def check_for_treasure(in_text, from_comment):
|
||||||
if '!slots' not in in_text and '!blackjack' not in in_text and '!wordle' not in in_text:
|
if '!slots' not in in_text and '!blackjack' not in in_text and '!wordle' not in in_text:
|
||||||
seed = random.randint(1, 1000)
|
seed = randint(1, 1000)
|
||||||
is_special = seed == 1000
|
is_special = seed == 1000
|
||||||
is_standard = seed >= 990
|
is_standard = seed >= 990
|
||||||
amount = 0
|
amount = 0
|
||||||
|
|
||||||
if is_special:
|
if is_special:
|
||||||
amount = random.randint(special_min, special_max)
|
amount = randint(special_min, special_max)
|
||||||
elif is_standard:
|
elif is_standard:
|
||||||
amount = random.randint(standard_min, standard_max)
|
amount = randint(standard_min, standard_max)
|
||||||
if random.randint(1, 100) > 90:
|
if randint(1, 100) > 90:
|
||||||
user = from_comment.author
|
user = from_comment.author
|
||||||
if amount > user.coins: amount = user.coins
|
if amount > user.coins: amount = user.coins
|
||||||
amount = -amount
|
amount = -amount
|
||||||
|
@ -24,6 +28,18 @@ def check_for_treasure(in_text, from_comment):
|
||||||
|
|
||||||
if amount != 0:
|
if amount != 0:
|
||||||
user = from_comment.author
|
user = from_comment.author
|
||||||
user.coins += amount
|
|
||||||
|
|
||||||
|
if amount > 0:
|
||||||
|
active_lottery = get_active_lottery()
|
||||||
|
lottery_tickets_seed = randint(1, 100)
|
||||||
|
lottery_tickets_instead = lottery_tickets_seed <= lotterizer_rate
|
||||||
|
|
||||||
|
if active_lottery and lottery_tickets_instead:
|
||||||
|
ticket_count = floor(amount / LOTTERY_TICKET_COST)
|
||||||
|
grant_lottery_tickets_to_user(user, ticket_count)
|
||||||
|
from_comment.treasure_amount = f'l{ticket_count}'
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
user.coins += amount
|
||||||
from_comment.treasure_amount = str(amount)
|
from_comment.treasure_amount = str(amount)
|
|
@ -138,3 +138,14 @@ def admin_level_required(x):
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
return wrapper_maker
|
return wrapper_maker
|
||||||
|
|
||||||
|
def lottery_required(f):
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
v = get_logged_in_user()
|
||||||
|
|
||||||
|
if not LOTTERY_ENABLED: abort(404)
|
||||||
|
|
||||||
|
return make_response(f(v=v))
|
||||||
|
|
||||||
|
wrapper.__name__ = f.__name__
|
||||||
|
return wrapper
|
|
@ -16,3 +16,4 @@ from .feeds import *
|
||||||
from .awards import *
|
from .awards import *
|
||||||
from .giphy import *
|
from .giphy import *
|
||||||
from .subs import *
|
from .subs import *
|
||||||
|
from .lottery import *
|
|
@ -932,18 +932,16 @@ def admin_removed_comments(v):
|
||||||
def agendaposter(user_id, v):
|
def agendaposter(user_id, v):
|
||||||
user = g.db.query(User).filter_by(id=user_id).one_or_none()
|
user = g.db.query(User).filter_by(id=user_id).one_or_none()
|
||||||
|
|
||||||
days = min(float(request.values.get("days", 30.0)), 30.0)
|
days = request.values.get("days")
|
||||||
|
if not days: days = 30.0
|
||||||
|
days = float(days)
|
||||||
|
days = min(days, 30.0)
|
||||||
|
|
||||||
expiry = int(time.time() + days*60*60*24)
|
expiry = int(time.time() + days*60*60*24)
|
||||||
|
|
||||||
user.agendaposter = expiry
|
user.agendaposter = expiry
|
||||||
g.db.add(user)
|
g.db.add(user)
|
||||||
|
|
||||||
for alt in user.alts:
|
|
||||||
if alt.admin_level: return {"error": "User is an admin!"}
|
|
||||||
alt.agendaposter = expiry
|
|
||||||
g.db.add(alt)
|
|
||||||
|
|
||||||
note = f"for {days} days"
|
note = f"for {days} days"
|
||||||
|
|
||||||
ma = ModAction(
|
ma = ModAction(
|
||||||
|
@ -1123,16 +1121,19 @@ def ban_user(user_id, v):
|
||||||
days = float(request.values.get("days")) if request.values.get('days') else 0
|
days = float(request.values.get("days")) if request.values.get('days') else 0
|
||||||
|
|
||||||
reason = request.values.get("reason", "").strip()[:256]
|
reason = request.values.get("reason", "").strip()[:256]
|
||||||
passed_reason = filter_emojis_only(reason)
|
reason = filter_emojis_only(reason)
|
||||||
|
|
||||||
if len(passed_reason) > 256: passed_reason = reason
|
if reason.startswith("/") and '\\' not in reason:
|
||||||
|
reason = f'<a href="{reason.split()[0]}">{reason}</a>'
|
||||||
|
|
||||||
user.ban(admin=v, reason=passed_reason, days=days)
|
if len(reason) > 256: reason = reason
|
||||||
|
|
||||||
|
user.ban(admin=v, reason=reason, days=days)
|
||||||
|
|
||||||
if request.values.get("alts"):
|
if request.values.get("alts"):
|
||||||
for x in user.alts:
|
for x in user.alts:
|
||||||
if x.admin_level: break
|
if x.admin_level: break
|
||||||
x.ban(admin=v, reason=passed_reason, days=days)
|
x.ban(admin=v, reason=reason, days=days)
|
||||||
|
|
||||||
if days:
|
if days:
|
||||||
if reason: text = f"@{v.username} has banned you for **{days}** days for the following reason:\n\n> {reason}"
|
if reason: text = f"@{v.username} has banned you for **{days}** days for the following reason:\n\n> {reason}"
|
||||||
|
@ -1268,6 +1269,10 @@ def ban_post(post_id, v):
|
||||||
v.coins += 1
|
v.coins += 1
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
|
|
||||||
|
if SITE == 'rdrama.net' and v.id != AEVANN_ID:
|
||||||
|
message = f"@{v.username} has removed [{post.title}]({post.shortlink})"
|
||||||
|
send_repeatable_notification(AEVANN_ID, message)
|
||||||
|
|
||||||
requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS, json={'files': [f"{SITE_FULL}/logged_out/"]}, timeout=5)
|
requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS, json={'files': [f"{SITE_FULL}/logged_out/"]}, timeout=5)
|
||||||
|
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
|
@ -1470,6 +1475,11 @@ def api_ban_comment(c_id, v):
|
||||||
target_comment_id=comment.id,
|
target_comment_id=comment.id,
|
||||||
)
|
)
|
||||||
g.db.add(ma)
|
g.db.add(ma)
|
||||||
|
|
||||||
|
if SITE == 'rdrama.net' and v.id != AEVANN_ID:
|
||||||
|
message = f"@{v.username} has removed [comment]({comment.shortlink})"
|
||||||
|
send_repeatable_notification(AEVANN_ID, message)
|
||||||
|
|
||||||
g.db.commit()
|
g.db.commit()
|
||||||
return {"message": "Comment removed!"}
|
return {"message": "Comment removed!"}
|
||||||
|
|
||||||
|
|
|
@ -413,7 +413,8 @@ def api_comment(v):
|
||||||
level=level+1,
|
level=level+1,
|
||||||
body_html=filter_emojis_only(option),
|
body_html=filter_emojis_only(option),
|
||||||
upvotes=0,
|
upvotes=0,
|
||||||
is_bot=True
|
is_bot=True,
|
||||||
|
ghost=c.ghost
|
||||||
)
|
)
|
||||||
|
|
||||||
g.db.add(c_option)
|
g.db.add(c_option)
|
||||||
|
@ -425,7 +426,8 @@ def api_comment(v):
|
||||||
level=level+1,
|
level=level+1,
|
||||||
body_html=filter_emojis_only(choice),
|
body_html=filter_emojis_only(choice),
|
||||||
upvotes=0,
|
upvotes=0,
|
||||||
is_bot=True
|
is_bot=True,
|
||||||
|
ghost=c.ghost
|
||||||
)
|
)
|
||||||
|
|
||||||
g.db.add(c_choice)
|
g.db.add(c_choice)
|
||||||
|
@ -454,7 +456,7 @@ def api_comment(v):
|
||||||
is_bot=True,
|
is_bot=True,
|
||||||
body_html=body_based_html,
|
body_html=body_based_html,
|
||||||
top_comment_id=c.top_comment_id,
|
top_comment_id=c.top_comment_id,
|
||||||
ghost=parent_post.ghost
|
ghost=c.ghost
|
||||||
)
|
)
|
||||||
|
|
||||||
g.db.add(c_based)
|
g.db.add(c_based)
|
||||||
|
@ -486,7 +488,7 @@ def api_comment(v):
|
||||||
is_bot=True,
|
is_bot=True,
|
||||||
body_html=body_jannied_html,
|
body_html=body_jannied_html,
|
||||||
top_comment_id=c.top_comment_id,
|
top_comment_id=c.top_comment_id,
|
||||||
ghost=parent_post.ghost
|
ghost=c.ghost
|
||||||
)
|
)
|
||||||
|
|
||||||
g.db.add(c_jannied)
|
g.db.add(c_jannied)
|
||||||
|
@ -522,7 +524,7 @@ def api_comment(v):
|
||||||
is_bot=True,
|
is_bot=True,
|
||||||
body_html=body_html2,
|
body_html=body_html2,
|
||||||
top_comment_id=c.top_comment_id,
|
top_comment_id=c.top_comment_id,
|
||||||
ghost=parent_post.ghost
|
ghost=c.ghost
|
||||||
)
|
)
|
||||||
|
|
||||||
g.db.add(c2)
|
g.db.add(c2)
|
||||||
|
@ -553,7 +555,7 @@ def api_comment(v):
|
||||||
is_bot=True,
|
is_bot=True,
|
||||||
body_html=body_html2,
|
body_html=body_html2,
|
||||||
top_comment_id=c.top_comment_id,
|
top_comment_id=c.top_comment_id,
|
||||||
ghost=parent_post.ghost,
|
ghost=c.ghost,
|
||||||
distinguish_level=6
|
distinguish_level=6
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -578,7 +580,7 @@ def api_comment(v):
|
||||||
is_bot=True,
|
is_bot=True,
|
||||||
body_html=body_html2,
|
body_html=body_html2,
|
||||||
top_comment_id=c.top_comment_id,
|
top_comment_id=c.top_comment_id,
|
||||||
ghost=parent_post.ghost,
|
ghost=c.ghost,
|
||||||
distinguish_level=6
|
distinguish_level=6
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -596,7 +598,7 @@ def api_comment(v):
|
||||||
is_bot=True,
|
is_bot=True,
|
||||||
body_html=body_html2,
|
body_html=body_html2,
|
||||||
top_comment_id=c.top_comment_id,
|
top_comment_id=c.top_comment_id,
|
||||||
ghost=parent_post.ghost,
|
ghost=c.ghost,
|
||||||
distinguish_level=6
|
distinguish_level=6
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -708,7 +710,8 @@ def edit_comment(cid, v):
|
||||||
level=c.level+1,
|
level=c.level+1,
|
||||||
body_html=filter_emojis_only(i.group(1)),
|
body_html=filter_emojis_only(i.group(1)),
|
||||||
upvotes=0,
|
upvotes=0,
|
||||||
is_bot=True
|
is_bot=True,
|
||||||
|
ghost=c.ghost
|
||||||
)
|
)
|
||||||
g.db.add(c_option)
|
g.db.add(c_option)
|
||||||
|
|
||||||
|
@ -720,7 +723,8 @@ def edit_comment(cid, v):
|
||||||
level=c.level+1,
|
level=c.level+1,
|
||||||
body_html=filter_emojis_only(i.group(1)),
|
body_html=filter_emojis_only(i.group(1)),
|
||||||
upvotes=0,
|
upvotes=0,
|
||||||
is_bot=True
|
is_bot=True,
|
||||||
|
ghost=c.ghost
|
||||||
)
|
)
|
||||||
g.db.add(c_choice)
|
g.db.add(c_choice)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
from files.__main__ import app, limiter
|
||||||
|
from files.helpers.wrappers import *
|
||||||
|
from files.helpers.alerts import *
|
||||||
|
from files.helpers.get import *
|
||||||
|
from files.helpers.const import *
|
||||||
|
from files.helpers.wrappers import *
|
||||||
|
from files.helpers.lottery import *
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/lottery/end")
|
||||||
|
@admin_level_required(3)
|
||||||
|
@lottery_required
|
||||||
|
def lottery_end(v):
|
||||||
|
success, message = end_lottery_session()
|
||||||
|
return {"message": message} if success else {"error": message}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/lottery/start")
|
||||||
|
@admin_level_required(3)
|
||||||
|
@lottery_required
|
||||||
|
def lottery_start(v):
|
||||||
|
start_new_lottery_session()
|
||||||
|
return {"message": "Lottery started."}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/lottery/buy")
|
||||||
|
@limiter.limit("3/second;100/minute;500/hour;1000/day")
|
||||||
|
@auth_required
|
||||||
|
@lottery_required
|
||||||
|
def lottery_buy(v):
|
||||||
|
success, message = purchase_lottery_ticket(v)
|
||||||
|
lottery, participants = get_active_lottery_stats()
|
||||||
|
|
||||||
|
if success:
|
||||||
|
return {"message": message, "stats": {"user": v.lottery_stats, "lottery": lottery, "participants": participants}}
|
||||||
|
else:
|
||||||
|
return {"error": message, "stats": {"user": v.lottery_stats, "lottery": lottery, "participants": participants}}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/lottery/active")
|
||||||
|
@limiter.limit("3/second;100/minute;500/hour;1000/day")
|
||||||
|
@auth_required
|
||||||
|
@lottery_required
|
||||||
|
def lottery_active(v):
|
||||||
|
lottery, participants = get_active_lottery_stats()
|
||||||
|
|
||||||
|
return {"message": "", "stats": {"user": v.lottery_stats, "lottery": lottery, "participants": participants}}
|
|
@ -483,7 +483,8 @@ def edit_post(pid, v):
|
||||||
level=1,
|
level=1,
|
||||||
body_html=filter_emojis_only(i.group(1)),
|
body_html=filter_emojis_only(i.group(1)),
|
||||||
upvotes=0,
|
upvotes=0,
|
||||||
is_bot=True
|
is_bot=True,
|
||||||
|
ghost=p.ghost
|
||||||
)
|
)
|
||||||
g.db.add(c)
|
g.db.add(c)
|
||||||
|
|
||||||
|
@ -494,7 +495,8 @@ def edit_post(pid, v):
|
||||||
level=1,
|
level=1,
|
||||||
body_html=filter_emojis_only(i.group(1)),
|
body_html=filter_emojis_only(i.group(1)),
|
||||||
upvotes=0,
|
upvotes=0,
|
||||||
is_bot=True
|
is_bot=True,
|
||||||
|
ghost=p.ghost
|
||||||
)
|
)
|
||||||
g.db.add(c)
|
g.db.add(c)
|
||||||
|
|
||||||
|
@ -1138,7 +1140,8 @@ def submit_post(v, sub=None):
|
||||||
level=1,
|
level=1,
|
||||||
body_html=filter_emojis_only(option),
|
body_html=filter_emojis_only(option),
|
||||||
upvotes=0,
|
upvotes=0,
|
||||||
is_bot=True
|
is_bot=True,
|
||||||
|
ghost=post.ghost
|
||||||
)
|
)
|
||||||
g.db.add(c)
|
g.db.add(c)
|
||||||
|
|
||||||
|
@ -1148,7 +1151,8 @@ def submit_post(v, sub=None):
|
||||||
level=1,
|
level=1,
|
||||||
body_html=filter_emojis_only(choice),
|
body_html=filter_emojis_only(choice),
|
||||||
upvotes=0,
|
upvotes=0,
|
||||||
is_bot=True
|
is_bot=True,
|
||||||
|
ghost=post.ghost
|
||||||
)
|
)
|
||||||
g.db.add(c)
|
g.db.add(c)
|
||||||
|
|
||||||
|
@ -1227,6 +1231,7 @@ def submit_post(v, sub=None):
|
||||||
stickied='AutoJanny',
|
stickied='AutoJanny',
|
||||||
distinguish_level=6,
|
distinguish_level=6,
|
||||||
body_html=body_jannied_html,
|
body_html=body_jannied_html,
|
||||||
|
ghost=post.ghost
|
||||||
)
|
)
|
||||||
|
|
||||||
g.db.add(c_jannied)
|
g.db.add(c_jannied)
|
||||||
|
@ -1329,7 +1334,8 @@ def submit_post(v, sub=None):
|
||||||
over_18=False,
|
over_18=False,
|
||||||
is_bot=True,
|
is_bot=True,
|
||||||
app_id=None,
|
app_id=None,
|
||||||
body_html=body_html
|
body_html=body_html,
|
||||||
|
ghost=post.ghost
|
||||||
)
|
)
|
||||||
|
|
||||||
g.db.add(c)
|
g.db.add(c)
|
||||||
|
|
|
@ -140,9 +140,9 @@ def stats(site=None):
|
||||||
|
|
||||||
stats.update(stats2)
|
stats.update(stats2)
|
||||||
|
|
||||||
bots = g.db.query(User).filter(User.id.in_(bots))
|
accs = g.db.query(User).filter(User.id.in_(bots))
|
||||||
|
|
||||||
for u in bots:
|
for u in accs:
|
||||||
g.db.add(u)
|
g.db.add(u)
|
||||||
|
|
||||||
if u.patron_utc and u.patron_utc < time.time():
|
if u.patron_utc and u.patron_utc < time.time():
|
||||||
|
@ -232,8 +232,16 @@ def cached_chart(kind, site):
|
||||||
)
|
)
|
||||||
today_cutoff = calendar.timegm(midnight_this_morning)
|
today_cutoff = calendar.timegm(midnight_this_morning)
|
||||||
|
|
||||||
if kind == "daily": day_cutoffs = [today_cutoff - 86400 * i for i in range(55)][1:]
|
if SITE == 'rdrama.net':
|
||||||
else: day_cutoffs = [today_cutoff - 86400 * 7 * i for i in range(55)][1:]
|
time_diff = time.time() - 1619827200
|
||||||
|
num_of_weeks = int(time_diff / 604800)
|
||||||
|
chart_width = int(num_of_weeks/1.4)
|
||||||
|
else:
|
||||||
|
num_of_weeks = 30
|
||||||
|
chart_width = 30
|
||||||
|
|
||||||
|
if kind == "daily": day_cutoffs = [today_cutoff - 86400 * i for i in range(num_of_weeks)][1:]
|
||||||
|
else: day_cutoffs = [today_cutoff - 86400 * 7 * i for i in range(num_of_weeks)][1:]
|
||||||
|
|
||||||
day_cutoffs.insert(0, calendar.timegm(now))
|
day_cutoffs.insert(0, calendar.timegm(now))
|
||||||
|
|
||||||
|
@ -245,11 +253,11 @@ def cached_chart(kind, site):
|
||||||
|
|
||||||
comment_stats = [g.db.query(Comment).filter(Comment.created_utc < day_cutoffs[i], Comment.created_utc > day_cutoffs[i + 1],Comment.is_banned == False, Comment.author_id.notin_((AUTOJANNY_ID,NOTIFICATIONS_ID))).count() for i in range(len(day_cutoffs) - 1)][::-1]
|
comment_stats = [g.db.query(Comment).filter(Comment.created_utc < day_cutoffs[i], Comment.created_utc > day_cutoffs[i + 1],Comment.is_banned == False, Comment.author_id.notin_((AUTOJANNY_ID,NOTIFICATIONS_ID))).count() for i in range(len(day_cutoffs) - 1)][::-1]
|
||||||
|
|
||||||
plt.rcParams["figure.figsize"] = (30, 20)
|
plt.rcParams["figure.figsize"] = (chart_width, 20)
|
||||||
|
|
||||||
signup_chart = plt.subplot2grid((30, 20), (0, 0), rowspan=6, colspan=30)
|
signup_chart = plt.subplot2grid((chart_width, 20), (0, 0), rowspan=6, colspan=chart_width)
|
||||||
posts_chart = plt.subplot2grid((30, 20), (10, 0), rowspan=6, colspan=30)
|
posts_chart = plt.subplot2grid((chart_width, 20), (10, 0), rowspan=6, colspan=chart_width)
|
||||||
comments_chart = plt.subplot2grid((30, 20), (20, 0), rowspan=6, colspan=30)
|
comments_chart = plt.subplot2grid((chart_width, 20), (20, 0), rowspan=6, colspan=chart_width)
|
||||||
|
|
||||||
signup_chart.grid(), posts_chart.grid(), comments_chart.grid()
|
signup_chart.grid(), posts_chart.grid(), comments_chart.grid()
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "admin/removed_posts.html" %}
|
{% extends "admin/removed_posts.html" %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
<title>Comments</title>
|
<title>Removed Comments</title>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block listing %}
|
{% block listing %}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "admin/reported_posts.html" %}
|
{% extends "admin/reported_posts.html" %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
<title>Removed Comments</title>
|
<title>Reported Comments</title>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block listing %}
|
{% block listing %}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
{% if v %}
|
{% if v %}
|
||||||
{% include "award_modal.html" %}
|
{% include "award_modal.html" %}
|
||||||
|
{% include "lottery_modal.html" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div style="display:none" id="popover">
|
<div style="display:none" id="popover">
|
||||||
|
@ -224,10 +225,14 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if c.treasure_amount and c.treasure_amount != '0' %}
|
{% if c.treasure_amount and c.treasure_amount != '0' %}
|
||||||
<img class="treasure" alt="treasure" src="/assets/images/chest.webp" width="20" />
|
{% if c.treasure_amount.startswith('l') %}
|
||||||
{% if '-' in c.treasure_amount %}
|
<img class="treasure" alt="treasure" src="/assets/images/treasure_tickets.webp" width="20" />
|
||||||
|
<em>Found {{c.treasure_amount.replace('l', '')}} Lottershe Tickets!</em>
|
||||||
|
{% elif '-' in c.treasure_amount %}
|
||||||
|
<img class="treasure" alt="treasure" src="/assets/images/treasure_mimic.webp" width="20" />
|
||||||
<em>A Mimic Ate {{c.treasure_amount.replace('-', '')}} Coins!</em>
|
<em>A Mimic Ate {{c.treasure_amount.replace('-', '')}} Coins!</em>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
<img class="treasure" alt="treasure" src="/assets/images/treasure_coins.webp" width="20" />
|
||||||
<em>Found {{c.treasure_amount}} Coins!</em>
|
<em>Found {{c.treasure_amount}} Coins!</em>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -463,9 +468,10 @@
|
||||||
{% if v %}
|
{% if v %}
|
||||||
<button style="margin-top:0.2rem" class="btn caction py-0 nobackground px-1 text-muted" data-bs-toggle="dropdown" aria-expanded="false"><i class="fas fa-ellipsis-h fa-fw"></i></button>
|
<button style="margin-top:0.2rem" class="btn caction py-0 nobackground px-1 text-muted" data-bs-toggle="dropdown" aria-expanded="false"><i class="fas fa-ellipsis-h fa-fw"></i></button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
|
|
||||||
{% if v.admin_level and v.id==c.author_id %}
|
{% if v.admin_level and v.id==c.author_id %}
|
||||||
<button id="undistinguish-{{c.id}}" class="dropdown-item list-inline-item d-none {% if c.distinguish_level %}d-md-block{% endif %} text-info" onclick="post_toast3(this,'/distinguish_comment/{{c.id}}','distinguish-{{c.id}}','undistinguish-{{c.id}}','no')"><i class="fas fa-id-badge text-info fa-fw"></i>Undistinguish</button>
|
<button id="undistinguish-{{c.id}}" class="dropdown-item list-inline-item d-none {% if c.distinguish_level %}d-md-block{% endif %} text-info" onclick="post_toast3(this,'/distinguish_comment/{{c.id}}','distinguish-{{c.id}}','undistinguish-{{c.id}}')"><i class="fas fa-id-badge text-info fa-fw"></i>Undistinguish</button>
|
||||||
<button id="distinguish-{{c.id}}" class="dropdown-item list-inline-item d-none {% if not c.distinguish_level %}d-md-block{% endif %} text-info" onclick="post_toast3(this,'/distinguish_comment/{{c.id}}','distinguish-{{c.id}}','undistinguish-{{c.id}}','yes')"><i class="fas fa-id-badge text-info fa-fw"></i>Distinguish</button>
|
<button id="distinguish-{{c.id}}" class="dropdown-item list-inline-item d-none {% if not c.distinguish_level %}d-md-block{% endif %} text-info" onclick="post_toast3(this,'/distinguish_comment/{{c.id}}','distinguish-{{c.id}}','undistinguish-{{c.id}}')"><i class="fas fa-id-badge text-info fa-fw"></i>Distinguish</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if v.id != c.author_id and not c.ghost %}
|
{% if v.id != c.author_id and not c.ghost %}
|
||||||
|
@ -650,11 +656,6 @@
|
||||||
{% if c.author_id == v.id %}
|
{% if c.author_id == v.id %}
|
||||||
<a role="button" data-bs-dismiss="modal" onclick="toggleEdit('{{c.id}}')" class="list-group-item"><i class="fas fa-edit mr-2"></i>Edit</a>
|
<a role="button" data-bs-dismiss="modal" onclick="toggleEdit('{{c.id}}')" class="list-group-item"><i class="fas fa-edit mr-2"></i>Edit</a>
|
||||||
|
|
||||||
{% if v.admin_level == 1 %}
|
|
||||||
<a id="distinguish2-{{c.id}}" class="list-group-item {% if c.distinguish_level %}d-none{% endif %} text-info" role="button" onclick="post_toast2(this,'/distinguish_comment/{{c.id}}','distinguish2-{{c.id}}','undistinguish2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-id-badge text-info mr-2"></i>Distinguish</a>
|
|
||||||
<a id="undistinguish2-{{c.id}}" class="list-group-item {% if not c.distinguish_level %}d-none{% endif %} text-info" role="button" onclick="post_toast2(this,'/distinguish_comment/{{c.id}}','distinguish2-{{c.id}}','undistinguish2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-id-badge text-info mr-2"></i>Undistinguish</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<a id="undelete2-{{c.id}}" class="{% if not c.deleted_utc %}d-none{% endif %} list-group-item text-success" role="button" onclick="post_toast2(this,'/undelete/comment/{{c.id}}', 'delete2-{{c.id}}', 'undelete2-{{c.id}}');document.getElementById('comment-{{c.id}}').classList.remove('deleted')" data-bs-dismiss="modal"><i class="far fa-trash-alt text-success mr-2"></i>Undelete</a>
|
<a id="undelete2-{{c.id}}" class="{% if not c.deleted_utc %}d-none{% endif %} list-group-item text-success" role="button" onclick="post_toast2(this,'/undelete/comment/{{c.id}}', 'delete2-{{c.id}}', 'undelete2-{{c.id}}');document.getElementById('comment-{{c.id}}').classList.remove('deleted')" data-bs-dismiss="modal"><i class="far fa-trash-alt text-success mr-2"></i>Undelete</a>
|
||||||
|
|
||||||
<a id="delete2-{{c.id}}" class="{% if c.deleted_utc %}d-none{% endif %} list-group-item text-danger" role="button" data-bs-toggle="modal" data-bs-dismiss="modal" data-bs-target="#deleteCommentModal" onclick="delete_commentModal('{{c.id}}')"><i class="far fa-trash-alt text-danger mr-2"></i>Delete</a>
|
<a id="delete2-{{c.id}}" class="{% if c.deleted_utc %}d-none{% endif %} list-group-item text-danger" role="button" data-bs-toggle="modal" data-bs-dismiss="modal" data-bs-target="#deleteCommentModal" onclick="delete_commentModal('{{c.id}}')"><i class="far fa-trash-alt text-danger mr-2"></i>Delete</a>
|
||||||
|
@ -846,7 +847,7 @@
|
||||||
|
|
||||||
{% if v %}
|
{% if v %}
|
||||||
<script src="/assets/js/marked.js?v=256"></script>
|
<script src="/assets/js/marked.js?v=256"></script>
|
||||||
<script src="/assets/js/comments_v.js?v=271"></script>
|
<script src="/assets/js/comments_v.js?v=272"></script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<script src="/assets/js/clipboard.js?v=250"></script>
|
<script src="/assets/js/clipboard.js?v=250"></script>
|
||||||
|
|
|
@ -261,7 +261,7 @@
|
||||||
{% if v and (v.is_banned or v.agendaposter) %}
|
{% if v and (v.is_banned or v.agendaposter) %}
|
||||||
<img alt="site banner" src="/assets/images/rDrama/banner2.webp?v=1" width="100%">
|
<img alt="site banner" src="/assets/images/rDrama/banner2.webp?v=1" width="100%">
|
||||||
{% else %}
|
{% else %}
|
||||||
<img alt="site banner" src="{{image}}" width="100%">
|
<img alt="site banner" src="{% if v %}{{image}}{% else %}/assets/images/rDrama/cached.webp?v=100{% endif %}" width="100%">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -77,6 +77,17 @@
|
||||||
{% if not err %}
|
{% if not err %}
|
||||||
<a class="mobile-nav-icon d-md-none" href="/random_user"><i class="fas fa-music align-middle text-gray-500 black"></i></a>
|
<a class="mobile-nav-icon d-md-none" href="/random_user"><i class="fas fa-music align-middle text-gray-500 black"></i></a>
|
||||||
<a class="mobile-nav-icon d-md-none" href="/random_post"><i class="fas fa-random align-middle text-gray-500 black"></i></a>
|
<a class="mobile-nav-icon d-md-none" href="/random_post"><i class="fas fa-random align-middle text-gray-500 black"></i></a>
|
||||||
|
{% if v and LOTTERY_ENABLED %}
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
class="mobile-nav-icon d-md-none"
|
||||||
|
title="Lottershe"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-dismiss="modal"
|
||||||
|
data-bs-target="#lotteryModal">
|
||||||
|
<i class="fas fa-ticket align-middle text-gray-500"></i>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
{% if v and v.admin_level > 1 %}
|
{% if v and v.admin_level > 1 %}
|
||||||
<a class="mobile-nav-icon d-md-none" href="/admin"><i class="fas fa-crown align-middle text-gray-500 black"></i></a>
|
<a class="mobile-nav-icon d-md-none" href="/admin"><i class="fas fa-crown align-middle text-gray-500 black"></i></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -103,6 +114,20 @@
|
||||||
<a class="nav-link" href="/random_post/" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Random post"><i class="fas fa-random"></i></a>
|
<a class="nav-link" href="/random_post/" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Random post"><i class="fas fa-random"></i></a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
{% if v and LOTTERY_ENABLED %}
|
||||||
|
<li class="nav-item d-flex align-items-center justify-content-center text-center mx-1">
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
class="nav-link"
|
||||||
|
title="Lottershe"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-dismiss="modal"
|
||||||
|
data-bs-target="#lotteryModal">
|
||||||
|
<i class="fas fa-ticket"></i>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<li class="nav-item d-flex align-items-center justify-content-center text-center mx-1">
|
<li class="nav-item d-flex align-items-center justify-content-center text-center mx-1">
|
||||||
<a class="nav-link" href="/chat/" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Chat"><i class="fas fa-messages"></i></a>
|
<a class="nav-link" href="/chat/" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Chat"><i class="fas fa-messages"></i></a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -0,0 +1,186 @@
|
||||||
|
{% if LOTTERY_ENABLED %}
|
||||||
|
<div
|
||||||
|
class="modal fade"
|
||||||
|
id="lotteryModal"
|
||||||
|
tabindex="-1"
|
||||||
|
role="dialog"
|
||||||
|
aria-labelledby="lotteryModalTitle"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<div class="modal-dialog lottery-modal--dialog" role="document">
|
||||||
|
<div class="modal-content lottery-modal--content">
|
||||||
|
<button
|
||||||
|
class="close lottery-modal--close"
|
||||||
|
data-bs-dismiss="modal"
|
||||||
|
aria-label="Close"
|
||||||
|
>
|
||||||
|
<span aria-hidden="true"><i class="far fa-times"></i></span>
|
||||||
|
</button>
|
||||||
|
<div class="lottery-modal--wrapper">
|
||||||
|
<div class="lottery-modal--image">
|
||||||
|
<img src="/assets/images/rDrama/lottery_modal.webp?v=2" />
|
||||||
|
<img
|
||||||
|
id="lotteryTicketPulled"
|
||||||
|
src="/assets/images/rDrama/lottery_modal_active.webp?v=2"
|
||||||
|
style="display: none"
|
||||||
|
/>
|
||||||
|
</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"
|
||||||
|
style="display: none"
|
||||||
|
onclick="endLotterySession()"
|
||||||
|
>
|
||||||
|
End Current Session
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-success"
|
||||||
|
id="startLotterySession"
|
||||||
|
style="display: none"
|
||||||
|
onclick="startLotterySession()"
|
||||||
|
>
|
||||||
|
Start New Session
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="lottery-modal--stat">
|
||||||
|
<div class="lottery-modal--stat-keys">
|
||||||
|
<div>Prize</div>
|
||||||
|
<div>Time Remaining</div>
|
||||||
|
<div>Tickets Sold This Session</div>
|
||||||
|
<div>Participants This Session</div>
|
||||||
|
</div>
|
||||||
|
<div class="lottery-modal--stat-values">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
id="prize-image"
|
||||||
|
alt="coins"
|
||||||
|
class="mr-1 ml-1"
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
data-bs-placement="bottom"
|
||||||
|
height="13"
|
||||||
|
src="/assets/images/rDrama/coins.webp?v=2"
|
||||||
|
title=""
|
||||||
|
aria-label="coins"
|
||||||
|
data-bs-original-title="coins"
|
||||||
|
style="display: none; position: relative; top: -2px"
|
||||||
|
/>
|
||||||
|
<span id="prize">-</span>
|
||||||
|
</div>
|
||||||
|
<div id="timeLeft">-</div>
|
||||||
|
<div id="ticketsSoldThisSession">-</div>
|
||||||
|
<div id="participantsThisSession">-</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="lottery-modal--stat">
|
||||||
|
<div class="lottery-modal--stat-keys">
|
||||||
|
<div>Tickets Owned This Session</div>
|
||||||
|
<div>Total Tickets Owned</div>
|
||||||
|
<div>Total Winnings</div>
|
||||||
|
</div>
|
||||||
|
<div class="lottery-modal--stat-values">
|
||||||
|
<div id="ticketsHeldCurrent">-</div>
|
||||||
|
<div id="ticketsHeldTotal">-</div>
|
||||||
|
<div id="winnings">-</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-success lottery-modal--action"
|
||||||
|
id="purchaseTicket"
|
||||||
|
onclick="purchaseLotteryTicket()"
|
||||||
|
disabled="true"
|
||||||
|
>
|
||||||
|
Purchase 1 for
|
||||||
|
<img
|
||||||
|
alt="coins"
|
||||||
|
class="mr-1 ml-1"
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
data-bs-placement="bottom"
|
||||||
|
height="13"
|
||||||
|
src="/assets/images/rDrama/coins.webp?v=2"
|
||||||
|
title=""
|
||||||
|
aria-label="coins"
|
||||||
|
data-bs-original-title="coins"
|
||||||
|
/>
|
||||||
|
|
||||||
|
12
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Success -->
|
||||||
|
<div
|
||||||
|
class="toast"
|
||||||
|
id="lottery-post-success"
|
||||||
|
style="
|
||||||
|
position: fixed;
|
||||||
|
bottom: 1.5rem;
|
||||||
|
margin: 0 auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 275px;
|
||||||
|
z-index: 1000;
|
||||||
|
"
|
||||||
|
role="alert"
|
||||||
|
aria-live="assertive"
|
||||||
|
aria-atomic="true"
|
||||||
|
data-bs-animation="true"
|
||||||
|
data-bs-autohide="true"
|
||||||
|
data-bs-delay="5000"
|
||||||
|
>
|
||||||
|
<div class="toast-body bg-success text-center text-white">
|
||||||
|
<i class="fas fa-comment-alt-smile mr-2"></i
|
||||||
|
><span id="lottery-post-success-text"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Error -->
|
||||||
|
<div
|
||||||
|
class="toast"
|
||||||
|
id="lottery-post-error"
|
||||||
|
style="
|
||||||
|
position: fixed;
|
||||||
|
bottom: 1.5rem;
|
||||||
|
margin: 0 auto;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 275px;
|
||||||
|
z-index: 1000;
|
||||||
|
"
|
||||||
|
role="alert"
|
||||||
|
aria-live="assertive"
|
||||||
|
aria-atomic="true"
|
||||||
|
data-bs-animation="true"
|
||||||
|
data-bs-autohide="true"
|
||||||
|
data-bs-delay="5000"
|
||||||
|
>
|
||||||
|
<div class="toast-body bg-danger text-center text-white">
|
||||||
|
<i class="fas fa-exclamation-circle mr-2"></i
|
||||||
|
><span id="lottery-post-error-text"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/assets/js/lottery_modal.js?v=249" data-cfasync="false"></script>
|
||||||
|
{% endif %}
|
|
@ -22,11 +22,6 @@
|
||||||
|
|
||||||
|
|
||||||
{% if v.id==p.author_id %}
|
{% if v.id==p.author_id %}
|
||||||
{% if v.admin_level == 1 %}
|
|
||||||
<button id="distinguish2-{{p.id}}" class="{% if p.distinguish_level %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" role="button" onclick="post_toast2(this,'/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-crown text-center mr-3"></i>Distinguish</button>
|
|
||||||
<button id="undistinguish2-{{p.id}}" class="{% if not p.distinguish_level %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left" role="button" onclick="post_toast2(this,'/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-crown text-center mr-3"></i>Undistinguish</button>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if request.path.startswith('/@') %}
|
{% if request.path.startswith('/@') %}
|
||||||
<button id="pin-profile2-{{p.id}}" class="{% if p.is_pinned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-muted text-left"role="button" onclick="post_toast2(this,'/pin/{{p.id}}','pin-profile2-{{p.id}}','unpin-profile2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Pin to profile</button>
|
<button id="pin-profile2-{{p.id}}" class="{% if p.is_pinned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-muted text-left"role="button" onclick="post_toast2(this,'/pin/{{p.id}}','pin-profile2-{{p.id}}','unpin-profile2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Pin to profile</button>
|
||||||
<button id="unpin-profile2-{{p.id}}" class="{% if not p.is_pinned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-muted text-left" role="button" onclick="post_toast2(this,'/pin/{{p.id}}','pin-profile2-{{p.id}}','unpin-profile2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Unpin from profile</button>
|
<button id="unpin-profile2-{{p.id}}" class="{% if not p.is_pinned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-muted text-left" role="button" onclick="post_toast2(this,'/pin/{{p.id}}','pin-profile2-{{p.id}}','unpin-profile2-{{p.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Unpin from profile</button>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
{% if v %}
|
{% if v %}
|
||||||
{% include "award_modal.html" %}
|
{% include "award_modal.html" %}
|
||||||
|
{% include "lottery_modal.html" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if request.host == 'pcmemes.net' %}
|
{% if request.host == 'pcmemes.net' %}
|
||||||
|
|
|
@ -44,12 +44,14 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="profilestuff" class="ml-3 w-100">
|
<div id="profilestuff" class="ml-3 w-100">
|
||||||
{% if u.is_suspended %}
|
{% if u.is_suspended %}
|
||||||
<h5 class="text-primary" id="profile--banned">BANNED USER{% if u.ban_reason %}:
|
<h5 class="text-primary" id="profile--banned">BANNED USER
|
||||||
{% if u.ban_reason_link %}<a href="{{u.ban_reason_link}}"><i class="fas fa-link"></i>{% endif %}
|
{% if u.ban_reason %}:
|
||||||
{{u.ban_reason | safe}}
|
{{u.ban_reason | safe}}
|
||||||
{% if u.ban_reason_link %}</a>{% endif %}
|
{% endif %}
|
||||||
{% endif %}</h5>
|
</h5>
|
||||||
{% if u.unban_utc %}<h5 class="text-primary" id="profile--unban">{{u.unban_string}}</h5>{% endif %}
|
{% if u.unban_utc %}
|
||||||
|
<h5 class="text-primary" id="profile--unban">{{u.unban_string}}</h5>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="d-flex align-items-center mt-1 mb-2">
|
<div class="d-flex align-items-center mt-1 mb-2">
|
||||||
<h1 class="font-weight-bolder h3 mb-0" id="profile--name" style="color: #{{u.namecolor}}"><span {% if u.patron %}class="patron" style="background-color:#{{u.namecolor}}"{% endif %}>{{u.username}}</span></h1>
|
<h1 class="font-weight-bolder h3 mb-0" id="profile--name" style="color: #{{u.namecolor}}"><span {% if u.patron %}class="patron" style="background-color:#{{u.namecolor}}"{% endif %}>{{u.username}}</span></h1>
|
||||||
|
@ -68,7 +70,7 @@
|
||||||
<span id="profile--verified"><i class="fas fa-badge-check align-middle ml-2 {% if u.verified=='Glowiefied' %}glow{% endif %}" style="color:{% if u.verifiedcolor %}#{{u.verifiedcolor}}{% else %}#1DA1F2{% endif %}" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{u.verified}}"></i></span>
|
<span id="profile--verified"><i class="fas fa-badge-check align-middle ml-2 {% if u.verified=='Glowiefied' %}glow{% endif %}" style="color:{% if u.verifiedcolor %}#{{u.verifiedcolor}}{% else %}#1DA1F2{% endif %}" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{u.verified}}"></i></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if u.admin_level > 1 or (u.admin_level == 1 and not(v and v.admin_level > 1)) %}
|
{% if u.admin_level > 1 %}
|
||||||
<span id="profile--mop">
|
<span id="profile--mop">
|
||||||
<i class="fas fa-broom text-admin align-middle ml-2" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Admin"></i>
|
<i class="fas fa-broom text-admin align-middle ml-2" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Admin"></i>
|
||||||
</span>
|
</span>
|
||||||
|
@ -388,7 +390,7 @@
|
||||||
<span id="profile--verified"><i class="fas fa-badge-check align-middle ml-2 {% if u.verified=='Glowiefied' %}glow{% endif %}" style="color:{% if u.verifiedcolor %}#{{u.verifiedcolor}}{% else %}#1DA1F2{% endif %}" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{u.verified}}"></i></span>
|
<span id="profile--verified"><i class="fas fa-badge-check align-middle ml-2 {% if u.verified=='Glowiefied' %}glow{% endif %}" style="color:{% if u.verifiedcolor %}#{{u.verifiedcolor}}{% else %}#1DA1F2{% endif %}" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{u.verified}}"></i></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if u.admin_level > 1 or (u.admin_level == 1 and not(v and v.admin_level > 1)) %}
|
{% if u.admin_level > 1 %}
|
||||||
<span id="profile--mop">
|
<span id="profile--mop">
|
||||||
<i class="fas fa-broom text-admin align-middle ml-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Admin"></i>
|
<i class="fas fa-broom text-admin align-middle ml-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Admin"></i>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{%-
|
{%-
|
||||||
set CACHE_VER = {
|
set CACHE_VER = {
|
||||||
'css/main.css': 281,
|
'css/main.css': 283,
|
||||||
'js/award_modal.js': 251,
|
'js/award_modal.js': 251,
|
||||||
'js/bootstrap.js': 257,
|
'js/bootstrap.js': 257,
|
||||||
'js/header.js': 268,
|
'js/header.js': 268,
|
||||||
|
|
62
schema.sql
62
schema.sql
|
@ -356,6 +356,40 @@ CREATE TABLE public.follows (
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: lotteries; Type: TABLE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.lotteries (
|
||||||
|
id integer NOT NULL,
|
||||||
|
is_active boolean DEFAULT false NOT NULL,
|
||||||
|
ends_at integer DEFAULT 0 NOT NULL,
|
||||||
|
prize integer DEFAULT 0 NOT NULL,
|
||||||
|
tickets_sold integer DEFAULT 0 NOT NULL,
|
||||||
|
winner_id integer
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: lotteries_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.lotteries_id_seq
|
||||||
|
AS integer
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: lotteries_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.lotteries_id_seq OWNED BY public.lotteries.id;
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: marseys; Type: TABLE; Schema: public; Owner: -
|
-- Name: marseys; Type: TABLE; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
@ -630,7 +664,10 @@ CREATE TABLE public.users (
|
||||||
subs_created integer DEFAULT 0 NOT NULL,
|
subs_created integer DEFAULT 0 NOT NULL,
|
||||||
deflector integer,
|
deflector integer,
|
||||||
reddit character varying(15) NOT NULL,
|
reddit character varying(15) NOT NULL,
|
||||||
animations boolean DEFAULT true NOT NULL
|
animations boolean DEFAULT true NOT NULL,
|
||||||
|
currently_held_lottery_tickets integer DEFAULT 0 NOT NULL,
|
||||||
|
total_held_lottery_tickets integer DEFAULT 0 NOT NULL,
|
||||||
|
total_lottery_winnings integer DEFAULT 0 NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -700,6 +737,13 @@ ALTER TABLE ONLY public.badge_defs ALTER COLUMN id SET DEFAULT nextval('public.b
|
||||||
ALTER TABLE ONLY public.comments ALTER COLUMN id SET DEFAULT nextval('public.comments_id_seq'::regclass);
|
ALTER TABLE ONLY public.comments ALTER COLUMN id SET DEFAULT nextval('public.comments_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: lotteries id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.lotteries ALTER COLUMN id SET DEFAULT nextval('public.lotteries_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: modactions id; Type: DEFAULT; Schema: public; Owner: -
|
-- Name: modactions id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
@ -848,6 +892,14 @@ ALTER TABLE ONLY public.follows
|
||||||
ADD CONSTRAINT follows_pkey PRIMARY KEY (target_id, user_id);
|
ADD CONSTRAINT follows_pkey PRIMARY KEY (target_id, user_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: lotteries lotteries_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.lotteries
|
||||||
|
ADD CONSTRAINT lotteries_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: marseys marseys_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
-- Name: marseys marseys_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
@ -1636,6 +1688,14 @@ ALTER TABLE ONLY public.exiles
|
||||||
ADD CONSTRAINT exile_user_fkey FOREIGN KEY (user_id) REFERENCES public.users(id);
|
ADD CONSTRAINT exile_user_fkey FOREIGN KEY (user_id) REFERENCES public.users(id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: lotteries fk_winner; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.lotteries
|
||||||
|
ADD CONSTRAINT fk_winner FOREIGN KEY (winner_id) REFERENCES public.users(id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: flags flags_post_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
|
-- Name: flags flags_post_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
|
Loading…
Reference in New Issue