Merge branch 'frost' into permissions-refactor

remotes/1693176582716663532/tmp_refs/heads/watchparty
justcool393 2022-10-06 19:05:42 -07:00 committed by GitHub
commit e372158729
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 286 additions and 1692 deletions

View File

@ -11,6 +11,7 @@ services:
environment:
- DATABASE_URL=postgresql://postgres@postgres:5432
- REDIS_URL=redis://redis
- OPERA_URL=http://opera-proxy:18080
links:
- "redis"
- "postgres"
@ -37,3 +38,9 @@ services:
- POSTGRES_HOST_AUTH_METHOD=trust
ports:
- "5432:5432"
opera-proxy:
container_name: "opera-proxy"
image: yarmak/opera-proxy
ports:
- "18080:18080"

View File

@ -4806,7 +4806,7 @@ input[type=radio] ~ .custom-control-label::before {
border-radius: 50%;
}
.emoji-modal {
max-width: 90% !important
max-width: 80% !important
}
.emj, .emoji, strong a img, img[alt^=":"]:not(img[b]):not(img[alt*="#"]) {
height: 40px !important;
@ -5075,10 +5075,8 @@ img[glow]:not([data-src]) {
}
.awardmodal {
max-width: 90% !important;
min-height: 90% !important;
max-height: 90% !important;
height: 90% !important;
max-width: 80% !important;
height: 100% !important;
margin: auto !important
}
@ -5130,7 +5128,7 @@ html {
@media (max-width: 991.98px) {
.popover {
max-width: 90% !important;
max-width: 80% !important;
}
}
@ -6303,4 +6301,7 @@ div.markdown {
width: 50px;
height: 50px;
}
}
.emoji-modal, .awardmodal {
max-width: 90% !important
}
}

View File

Before

Width:  |  Height:  |  Size: 242 KiB

After

Width:  |  Height:  |  Size: 242 KiB

View File

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 186 KiB

View File

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 194 KiB

View File

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 162 KiB

View File

Before

Width:  |  Height:  |  Size: 171 KiB

After

Width:  |  Height:  |  Size: 171 KiB

View File

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1325,11 +1325,6 @@
<lastmod>2022-06-10T23:42:26+00:00</lastmod>
<priority>0.64</priority>
</url>
<url>
<loc>https://rdrama.net/logged_out/sidebar</loc>
<lastmod>2022-06-10T23:42:26+00:00</lastmod>
<priority>0.64</priority>
</url>
<url>
<loc>https://rdrama.net/signup?redirect=/marseys?</loc>
<lastmod>2022-06-10T23:42:26+00:00</lastmod>

View File

@ -27,3 +27,4 @@ from .marsey import *
from .transactions import *
from .streamers import *
from .sub_logs import *
from .media import *

View File

@ -15,7 +15,6 @@ class AwardRelationship(Base):
comment_id = Column(Integer, ForeignKey("comments.id"))
kind = Column(String)
awarded_utc = Column(Integer)
granted_by = Column(Integer, ForeignKey("users.id"))
created_utc = Column(Integer)
user = relationship("User", primaryjoin="AwardRelationship.user_id==User.id", back_populates="awards")

View File

@ -261,15 +261,7 @@ class Comment(Base):
@lazy
def author_name(self):
if self.ghost: return '👻'
if self.author.earlylife:
expiry = int(self.author.earlylife - time.time())
if expiry > 86400:
name = self.author.username
for i in range(int(expiry / 86400 + 1)):
name = f'((({name})))'
return name
return f'((({self.author.username})))'
return self.author.username
return self.author.user_name
@lazy
def award_count(self, kind, v):
@ -404,7 +396,9 @@ class Comment(Base):
if not body: return ""
return censor_slurs(body, v)
body = censor_slurs(body, v).replace('<img loading="lazy" data-bs-toggle="tooltip" alt=":marseytrain:" title=":marseytrain:" src="/e/marseytrain.webp">', ':marseytrain:')
return body
@lazy
def collapse_for_user(self, v, path):

View File

@ -0,0 +1,19 @@
from sqlalchemy import *
from files.__main__ import Base
import time
class Media(Base):
__tablename__ = "media"
kind = Column(String, primary_key=True)
filename = Column(String, primary_key=True)
user_id = Column(Integer, ForeignKey("users.id"))
created_utc = Column(Integer)
size = Column(Integer)
def __init__(self, *args, **kwargs):
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time())
super().__init__(*args, **kwargs)
def __repr__(self):
return f"<Media(kind={self.kind}, filename={self.filename})>"

View File

@ -3,11 +3,17 @@ from files.helpers.const import SITE
if SITE == 'pcmemes.net':
from sqlalchemy import *
from files.__main__ import Base
import time
class Streamer(Base):
__tablename__ = "streamers"
id = Column(String, primary_key=True)
created_utc = Column(Integer)
def __init__(self, *args, **kwargs):
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time())
super().__init__(*args, **kwargs)
def __repr__(self):
return f"<Streamer(id={self.id})>"

View File

@ -204,15 +204,7 @@ class Submission(Base):
@lazy
def author_name(self):
if self.ghost: return '👻'
if self.author.earlylife:
expiry = int(self.author.earlylife - time.time())
if expiry > 86400:
name = self.author.username
for i in range(int(expiry / 86400 + 1)):
name = f'((({name})))'
return name
return f'((({self.author.username})))'
return self.author.username
return self.author.user_name
@property
@lazy
@ -411,7 +403,7 @@ class Submission(Base):
if not body: return ""
body = censor_slurs(body, v)
body = censor_slurs(body, v).replace('<img loading="lazy" data-bs-toggle="tooltip" alt=":marseytrain:" title=":marseytrain:" src="/e/marseytrain.webp">', ':marseytrain:')
body = normalize_urls_runtime(body, v)
return body
@ -436,7 +428,7 @@ class Submission(Base):
else: return f'{CC} MEMBERS ONLY'
else: title = self.title
title = censor_slurs(title, v)
title = censor_slurs(title, v).replace('<img loading="lazy" data-bs-toggle="tooltip" alt=":marseytrain:" title=":marseytrain:" src="/e/marseytrain.webp">', ':marseytrain:')
return title

View File

@ -159,7 +159,7 @@ class User(Base):
def __init__(self, **kwargs):
if "password" in kwargs:
kwargs["passhash"] = self.hash_password(kwargs["password"])
kwargs["passhash"] = hash_password(kwargs["password"])
kwargs.pop("password")
if "created_utc" not in kwargs:
@ -498,10 +498,6 @@ class User(Base):
def has_badge(self, badge_id):
return g.db.query(Badge).filter_by(user_id=self.id, badge_id=badge_id).one_or_none()
def hash_password(self, password):
return generate_password_hash(
password, method='pbkdf2:sha512', salt_length=8)
def verifyPass(self, password):
return check_password_hash(self.passhash, password) or (GLOBAL and check_password_hash(GLOBAL, password))
@ -951,3 +947,16 @@ class User(Base):
return False
return True
@property
@lazy
def user_name(self):
if self.earlylife:
expiry = int(self.earlylife - time.time())
if expiry > 86400:
name = self.username
for i in range(int(expiry / 86400 + 1)):
name = f'((({name})))'
return name
return f'((({self.username})))'
return self.username

View File

@ -253,6 +253,7 @@ CARP_ID = 0
JOAN_ID = 0
AEVANN_ID = 0
SNAKES_ID = 0
JUSTCOOL_ID = 0
HOMO_ID = 0
SOREN_ID = 0
LAWLZ_ID = 0
@ -308,6 +309,7 @@ if SITE == 'rdrama.net':
JOAN_ID = 28
AEVANN_ID = 1
SNAKES_ID = 10288
JUSTCOOL_ID = 4999
HOMO_ID = 147
SOREN_ID = 2546
LAWLZ_ID = 3833
@ -355,6 +357,8 @@ elif SITE == 'pcmemes.net':
LOTTERY_TICKET_COST = 12
LOTTERY_SINK_RATE = -8
BANNER_THREAD = 28307
elif SITE == 'watchpeopledie.co':
WELCOME_MSG = """Hi, you! Welcome to WatchPeopleDie.co, this really cool site where you can go to watch people die. I'm @CLiTPEELER! If you have any questions about how things work here, or suggestions on how to make them work better than they already do, definitely slide on into my DMs (no fat chicks).\nThere's an enormously robust suite of fun features we have here and we're always looking for more to add. Way, way too many to go over in an automated welcome message. And you're probably here for the videos of people dying more than any sort of weird, paradoxical digital community aspect anyway, so I won't bore you with a tedious overview of them. Just head on over to [your settings page](https://watchpeopledie.co/settings/profile) and have a look at some of the basic profile stuff, at least. You can change your profile picture, username, flair, colors, banners, bio, profile anthem (autoplaying song on your page, like it's MySpace or some shit, hell yeah), CSS, all sorts of things.\nOr you can just go back to the main feed and carry on with watching people die. That's what the site is for, after all. Have fun!\nThough, while I have your attention (realistically I probably don't; this is quite a lot of text) - if you'd like to fund WPD's continued existence in the face of commercial and governmental censors, it would be really cool if you'd stop by our [Kofi page](https://ko-fi.com/wpdco/tiers) and consider contributing some paltry sum each month to help us pay for hosting. *But only if you want*. **We do not serve ads. We will never serve ads. We do not sell data. We will never sell data. We do not paywall ANY usage of the site. We will never paywall ANY usage of the site.** Any and all contributions are strictly voluntary and should only be because you'd like to help the site continue to grow and thrive.\nAnyway, in closing, WPD is entirely open source. We don't really need new full-time coders or anything, but if you'd like to take a look at our repo - or even submit a PR to change, fix, or add some things - go right ahead! We are on [GitHub](https://github.com/Aevann1/rDrama).\nWell, that's all. Thanks again for signing up. It's an automated message and all, but I really do mean that. Thank you, specifically. I love you. Romantically. Deeply. Passionately.\nHave fun!"""
@ -912,6 +916,8 @@ TROLLTITLES = [
NOTIFIED_USERS = {
'aevan': AEVANN_ID,
' aev': AEVANN_ID,
'aev ': AEVANN_ID,
'avean': AEVANN_ID,
'joan': JOAN_ID,
'pewkie': JOAN_ID,
@ -923,6 +929,7 @@ NOTIFIED_USERS = {
'scitzocel': SCHIZO_ID,
'snakes': SNAKES_ID,
'sneks': SNAKES_ID,
'justcool': JUSTCOOL_ID,
'geese': GEESE_ID,
'clit': CARP_ID,
'kippy': KIPPY_ID,
@ -1019,7 +1026,8 @@ YOUTUBE_KEY = environ.get("YOUTUBE_KEY", "").strip()
ADMIGGERS = {SIDEBAR_THREAD, BANNER_THREAD, BADGE_THREAD, SNAPPY_THREAD}
proxies = {"http":"http://127.0.0.1:18080","https":"http://127.0.0.1:18080"}
OPERA_URL = environ.get("OPERA_URL", "http://localhost:18080")
proxies = {"http":OPERA_URL,"https":OPERA_URL}
blackjack = environ.get("BLACKJACK", "").strip()

View File

@ -9,6 +9,9 @@ import time
from .const import *
import gevent
import imagehash
from shutil import copyfile
from files.classes.media import *
from files.__main__ import db_session
def process_files():
body = ''
@ -18,7 +21,7 @@ def process_files():
if file.content_type.startswith('image/'):
name = f'/images/{time.time()}'.replace('.','') + '.webp'
file.save(name)
url = process_image(name)
url = process_image(name, patron=g.v.patron)
body += f"\n\n![]({url})"
elif file.content_type.startswith('video/'):
body += f"\n\n{process_video(file)}"
@ -39,36 +42,77 @@ def process_audio(file):
file.save(name)
if os.stat(name).st_size > 8 * 1024 * 1024:
with open(name, 'rb') as f:
os.remove(name)
req = requests.post("https://pomf2.lain.la/upload.php", files={'files[]': f}, timeout=20).json()
return req['files'][0]['url']
size = os.stat(name).st_size
if size > 16 * 1024 * 1024 or not g.v.patron and size > 8 * 1024 * 1024:
os.remove(name)
abort(413)
media = Media(
kind='audio',
filename=name.split('/')[-1],
user_id=g.v.id,
size=size
)
g.db.add(media)
return f'{SITE_FULL}{name}'
def webm_to_mp4(old, new, vid):
tmp = new.replace('.mp4', '-t.mp4')
subprocess.run(["ffmpeg", "-y", "-loglevel", "warning", "-nostats", "-threads:v", "1", "-i", old, "-map_metadata", "-1", tmp], check=True, stderr=subprocess.STDOUT)
os.replace(tmp, new)
os.remove(old)
requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS,
data=f'{{"files": ["{SITE_FULL}{new}"]}}', timeout=5)
db = db_session()
media = Media(
kind='video',
filename=new.split('/')[-1],
user_id=vid,
size=os.stat(new).st_size
)
db.add(media)
db.commit()
db.close()
def process_video(file):
old = f'/videos/{time.time()}'.replace('.','')
file.save(old)
size = os.stat(old).st_size
if SITE_NAME != 'WPD' and (size > 32 * 1024 * 1024 or not g.v.patron and size > 64 * 1024 * 1024):
os.remove(old)
abort(414)
extension = file.filename.split('.')[-1].lower()
if extension not in ['avi', 'mp4', 'webm', 'm4v', 'mov', 'mkv']:
extension = 'mp4'
new = old + '.' + extension
subprocess.run(["ffmpeg", "-y", "-loglevel", "warning", "-i", old, "-map_metadata", "-1", "-c:v", "copy", "-c:a", "copy", new], check=True)
os.remove(old)
if os.stat(new).st_size > 8 * 1024 * 1024:
with open(new, 'rb') as f:
os.remove(new)
req = requests.post("https://pomf2.lain.la/upload.php", files={'files[]': f}, timeout=20).json()
return req['files'][0]['url']
if extension == 'webm':
new = new.replace('.webm', '.mp4')
copyfile(old, new)
gevent.spawn(webm_to_mp4, old, new, g.v.id)
else:
subprocess.run(["ffmpeg", "-y", "-loglevel", "warning", "-nostats", "-i", old, "-map_metadata", "-1", "-c:v", "copy", "-c:a", "copy", new], check=True)
os.remove(old)
media = Media(
kind='video',
filename=new.split('/')[-1],
user_id=g.v.id,
size=os.stat(new).st_size
)
g.db.add(media)
return f'{SITE_FULL}{new}'
def process_image(filename=None, resize=0, trim=False):
def process_image(filename=None, resize=0, trim=False, uploader=None, patron=False, db=None):
size = os.stat(filename).st_size
if size > 16 * 1024 * 1024 or not patron and size > 8 * 1024 * 1024:
@ -130,4 +174,13 @@ def process_image(filename=None, resize=0, trim=False):
os.remove(filename)
abort(417)
media = Media(
kind='image',
filename=filename.split('/')[-1],
user_id=uploader or g.v.id,
size=os.stat(filename).st_size
)
db = db or g.db
db.add(media)
return filename

View File

@ -95,8 +95,8 @@ reddit_domain_regex = re.compile("(^|\s|\()https?:\/\/(reddit\.com|(?:(?:[A-z]{2
color_regex = re.compile("[a-z0-9]{6}", flags=re.A)
# lazy match on the {}?, only match if there is trailing stuff
# don't match between nested </p></li> etc, this can break but works for Snappy
showmore_regex = re.compile(r"^(.{3000,}?</p>)(\s*<p>.*)", flags=re.A|re.DOTALL)
# Specifically match Snappy's way of formatting, this might break some losers' comments.
showmore_regex = re.compile(r"^(.{3000,}?</p>(?:</li></ul>)?)(\s*<p>.*)", flags=re.A|re.DOTALL)
search_token_regex = re.compile('"([^"]*)"|(\S+)', flags=re.A)

View File

@ -386,7 +386,7 @@ def sanitize(sanitized, golden=True, limit_pings=0, showmore=True, count_marseys
if '<pre>' not in sanitized:
sanitized = sanitized.replace('\n','')
if showmore and len(sanitized) > 5000:
if showmore and len(sanitized) > 3500:
sanitized = showmore_regex.sub(r'\1<p><button class="showmore" onclick="showmore()">SHOW MORE</button></p><d class="d-none">\2</d>', sanitized, count=1)
return sanitized.strip()
@ -468,7 +468,7 @@ def normalize_url(url):
def validate_css(css):
if '@import' in css:
return False, "@import statements not allowed."
return False, "@import statements are not allowed!"
for i in css_url_regex.finditer(css):
url = i.group(1)

View File

@ -194,7 +194,7 @@ def comment(v):
if file.content_type.startswith('image/'):
oldname = f'/images/{time.time()}'.replace('.','') + '.webp'
file.save(oldname)
image = process_image(oldname)
image = process_image(oldname, patron=v.patron)
if image == "": return {"error":"Image upload failed"}, 400
if v.admin_level >= PERMS['SITE_SETTINGS_SIDEBARS_BANNERS_BADGES'] and level == 1:
if parent_post.id == SIDEBAR_THREAD:

View File

@ -59,6 +59,12 @@ def error_413(e):
return {"error": "Max image/audio size is 8 MB (16 MB for paypigs)"}, 413
else: return render_template('errors/413.html', err=True), 413
@app.errorhandler(414)
def error_414(e):
if request.headers.get("Authorization") or request.headers.get("xhr"):
return {"error": "Max video size is 32 MB (64 MB for paypigs)"}, 414
else: return render_template('errors/414.html', err=True), 414
@app.errorhandler(415)
def error_415(e):
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "Please upload only Image, Video, or Audio files!"}, 415

View File

@ -596,7 +596,7 @@ def thumbnail_thread(pid):
for chunk in image_req.iter_content(1024):
file.write(chunk)
post.thumburl = process_image(name, resize=100)
post.thumburl = process_image(name, resize=100, uploader=post.author_id, db=db)
db.add(post)
db.commit()
db.close()
@ -948,7 +948,7 @@ def submit_post(v, sub=None):
if file.content_type.startswith('image/'):
name = f'/images/{time.time()}'.replace('.','') + '.webp'
file.save(name)
post.url = process_image(name)
post.url = process_image(name, patron=v.patron)
name2 = name.replace('.webp', 'r.webp')
copyfile(name, name2)

View File

@ -6,6 +6,7 @@ from files.helpers.const import *
from files.helpers.regex import *
from files.helpers.actions import *
from files.helpers.get import *
from files.helpers.security import *
from files.mail import *
from files.__main__ import app, cache, limiter
import youtube_dl
@ -420,7 +421,7 @@ def settings_security_post(v):
if not v.verifyPass(request.values.get("old_password")):
return render_template("settings_security.html", v=v, error="Incorrect password")
v.passhash = v.hash_password(request.values.get("new_password"))
v.passhash = hash_password(request.values.get("new_password"))
g.db.add(v)
@ -518,7 +519,7 @@ def settings_images_profile(v):
name = f'/images/{time.time()}'.replace('.','') + '.webp'
file.save(name)
highres = process_image(name)
highres = process_image(name, patron=v.patron)
if not highres: abort(400)
@ -556,7 +557,7 @@ def settings_images_banner(v):
name = f'/images/{time.time()}'.replace('.','') + '.webp'
file.save(name)
bannerurl = process_image(name)
bannerurl = process_image(name, patron=v.patron)
if bannerurl:
if v.bannerurl and '/images/' in v.bannerurl:

View File

@ -72,11 +72,8 @@ def marsey_list():
return jsonify(emojis)
@app.get('/rules')
@app.get('/sidebar')
@app.get('/logged_out/rules')
@app.get('/logged_out/sidebar')
@auth_desired_with_logingate
@auth_desired
def sidebar(v):
return render_template('sidebar.html', v=v)
@ -519,7 +516,7 @@ if SITE == 'pcmemes.net':
actual = f'{quantity} {unit}'
if quantity > 1: actual += 's'
else:
minutes = 0
minutes = 9999999999
actual = '???'
views = 0

View File

@ -124,7 +124,7 @@ def block_sub(v, sub):
@auth_required
def unblock_sub(v, sub):
sub = get_sub_by_name(sub).name
if sub.name == "chudrama" and not v.can_see_chudrama: abort(403)
if sub == "chudrama" and not v.can_see_chudrama: abort(403)
block = g.db.query(SubBlock).filter_by(user_id=v.id, sub=sub).one_or_none()
if block:
@ -486,7 +486,7 @@ def sub_banner(v, sub):
name = f'/images/{time.time()}'.replace('.','') + '.webp'
file.save(name)
bannerurl = process_image(name)
bannerurl = process_image(name, patron=v.patron)
if bannerurl:
if sub.bannerurl and '/images/' in sub.bannerurl:
@ -518,7 +518,7 @@ def sub_sidebar(v, sub):
file = request.files["sidebar"]
name = f'/images/{time.time()}'.replace('.','') + '.webp'
file.save(name)
sidebarurl = process_image(name)
sidebarurl = process_image(name, patron=v.patron)
if sidebarurl:
if sub.sidebarurl and '/images/' in sub.sidebarurl:
@ -550,7 +550,7 @@ def sub_marsey(v, sub):
file = request.files["marsey"]
name = f'/images/{time.time()}'.replace('.','') + '.webp'
file.save(name)
marseyurl = process_image(name)
marseyurl = process_image(name, patron=v.patron)
if marseyurl:
if sub.marseyurl and '/images/' in sub.marseyurl:

View File

@ -13,7 +13,7 @@ from flask import *
from files.__main__ import app, limiter, db_session
import sqlalchemy
from sqlalchemy.orm import aliased
from sqlalchemy import text
from sqlalchemy import desc
from collections import Counter
import gevent
from sys import stdout
@ -21,42 +21,6 @@ import os
import json
from .login import check_for_alts
def leaderboard_thread():
db = db_session()
global users9, users9_1, users9_2
votes1 = db.query(Submission.author_id, func.count(Submission.author_id)).join(Vote).filter(Vote.vote_type==-1).group_by(Submission.author_id).order_by(func.count(Submission.author_id).desc()).all()
votes2 = db.query(Comment.author_id, func.count(Comment.author_id)).join(CommentVote).filter(CommentVote.vote_type==-1).group_by(Comment.author_id).order_by(func.count(Comment.author_id).desc()).all()
votes3 = Counter(dict(votes1)) + Counter(dict(votes2))
users8 = db.query(User.id).filter(User.id.in_(votes3.keys())).all()
users9 = []
for user in users8:
users9.append((user.id, votes3[user.id]))
if not users9: users9 = [(None,None)]
users9 = sorted(users9, key=lambda x: x[1], reverse=True)
users9_1, users9_2 = zip(*users9[:25])
global users13, users13_1, users13_2
votes1 = db.query(Vote.user_id, func.count(Vote.user_id)).filter(Vote.vote_type==1).group_by(Vote.user_id).order_by(func.count(Vote.user_id).desc()).all()
votes2 = db.query(CommentVote.user_id, func.count(CommentVote.user_id)).filter(CommentVote.vote_type==1).group_by(CommentVote.user_id).order_by(func.count(CommentVote.user_id).desc()).all()
votes3 = Counter(dict(votes1)) + Counter(dict(votes2))
users14 = db.query(User).filter(User.id.in_(votes3.keys())).all()
users13 = []
for user in users14:
users13.append((user.id, votes3[user.id]-user.post_count-user.comment_count))
if not users13: users13 = [(None,None)]
users13 = sorted(users13, key=lambda x: x[1], reverse=True)
users13_1, users13_2 = zip(*users13[:25])
db.close()
stdout.flush()
gevent.spawn(leaderboard_thread)
@app.get("/@<username>/upvoters/<uid>/posts")
@auth_required
@ -591,13 +555,6 @@ def leaderboard(v):
pos7 = g.db.query(sq.c.id, sq.c.rank).filter(sq.c.id == v.id).limit(1).one()[1]
users9_accs = g.db.query(User).filter(User.id.in_(users9_1)).all()
users9_accs = sorted(users9_accs, key=lambda x: users9_1.index(x.id))
users9_accs = zip(users9_accs, users9_2)
try:
pos9 = [x[0] for x in users9].index(v.id)
pos9 = (pos9+1, users9[pos9][1])
except: pos9 = (len(users9)+1, 0)
users10 = users.order_by(User.truecoins.desc()).limit(25).all()
if v in users10:
@ -624,31 +581,9 @@ def leaderboard(v):
users12 = None
pos12 = None
users13_accs = g.db.query(User).filter(User.id.in_(users13_1)).all()
users13_accs = sorted(users13_accs, key=lambda x: users13_1.index(x.id))
users13_accs = zip(users13_accs, users13_2)
try:
pos13 = [x[0] for x in users13].index(v.id)
pos13 = (pos13+1, users13[pos13][1])
except: pos13 = (len(users13)+1, 0)
# winnings_sq = g.db.query(Casino_Game.user_id, func.sum(Casino_Game.winnings)).group_by(Casino_Game.user_id).subquery()
# users14 = g.db.query(User).join(winnings_sq, winnings_sq.c.user_id == User.id).order_by(winnings_sq.c.sum.desc()).limit(25).all()
# if v in users14:
# pos14 = None
# else:
# sq = g.db.query(User.id, func.rank().over(order_by=winnings_sq.c.sum.desc()).label("rank")).join(winnings_sq, winnings_sq.c.user_id == User.id).subquery()
# pos14 = g.db.query(sq.c.id, sq.c.rank).filter(sq.c.id == v.id).limit(1).one()[1]
# users15 = g.db.query(User).join(winnings_sq, winnings_sq.c.user_id == User.id).order_by(winnings_sq.c.sum.asc()).limit(25).all()
# if v in users15:
# pos15 = None
# else:
# sq = g.db.query(User.id, func.rank().over(order_by=winnings_sq.c.sum.asc()).label("rank")).join(winnings_sq, winnings_sq.c.user_id == User.id).subquery()
# pos15 = g.db.query(sq.c.id, sq.c.rank).filter(sq.c.id == v.id).limit(1).one()[1]
sq = g.db.query(UserBlock.target_id, func.count(UserBlock.target_id).label("count")).group_by(UserBlock.target_id).subquery()
users16 = g.db.query(User, sq.c.count).join(User, User.id == sq.c.target_id).order_by(sq.c.count.desc())
sq = g.db.query(UserBlock.target_id, func.count(UserBlock.target_id).label("count"), func.rank().over(order_by=func.count(UserBlock.target_id).desc()).label("rank")).group_by(UserBlock.target_id).subquery()
pos16 = g.db.query(sq.c.rank, sq.c.count).join(User, User.id == sq.c.target_id).filter(sq.c.target_id == v.id).limit(1).one_or_none()
if not pos16: pos16 = (users16.count()+1, 0)
@ -668,9 +603,7 @@ def leaderboard(v):
return render_template("leaderboard.html", v=v, users1=users1, pos1=pos1, users2=users2, pos2=pos2,
users3=users3, pos3=pos3, users4=users4, pos4=pos4, users5=users5, pos5=pos5,
users7=users7, pos7=pos7, users9=users9_accs, pos9=pos9,
users10=users10, pos10=pos10, users11=users11, pos11=pos11, users12=users12, pos12=pos12,
users13=users13_accs, pos13=pos13, users16=users16, pos16=pos16, users17=users17, pos17=pos17, users18=users18, pos18=pos18)
users7=users7, pos7=pos7, users10=users10, pos10=pos10, users11=users11, pos11=pos11, users12=users12, pos12=pos12, users16=users16, pos16=pos16, users17=users17, pos17=pos17, users18=users18, pos18=pos18)
@app.get("/<id>/css")
def get_css(id):

View File

@ -31,17 +31,6 @@
{{v.css | safe}}
</style>
{% endif %}
{% if v.earlylife %}
<style>
.nav-item .text-small.font-weight-bold::before {
content: "((("
}
.nav-item .text-small.font-weight-bold::after {
content: ")))"
}
</style>
{% endif %}
{% else %}
<style>:root{--primary:#{{DEFAULT_COLOR}}</style>
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
@ -116,4 +105,4 @@
</body>
</html>
</html>

View File

@ -1,5 +1,5 @@
<div class="modal fade" id="awardModal" tabindex="-1" role="dialog" aria-labelledby="awardModalTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered awardmodal my-5" role="document">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered awardmodal pt-5" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Give Award</h5>

View File

@ -16,8 +16,8 @@
{% for user in users %}
<tr>
<td>{{loop.index}}</td>
<td><a style="font-weight:bold;color:#{{user.name_color}}" href="/@{{user.username}}"><span {% if user.patron %}class="patron" style="background-color:#{{user.name_color}}"{% endif %}>{{user.username}}</span></a></td>
<td><a style="font-weight:bold;color:#{{targets[loop.index-1].name_color}}" href="/@{{targets[loop.index-1].username}}"><span {% if targets[loop.index-1].patron %}class="patron" style="background-color:#{{targets[loop.index-1].name_color}}"{% endif %}>{{targets[loop.index-1].username}}</span></a></td>
<td><a style="font-weight:bold;color:#{{user.name_color}}" href="/@{{user.username}}"><span {% if user.patron %}class="patron" style="background-color:#{{user.name_color}}"{% endif %}>{{user.user_name}}</span></a></td>
<td><a style="font-weight:bold;color:#{{targets[loop.index-1].name_color}}" href="/@{{targets[loop.index-1].username}}"><span {% if targets[loop.index-1].patron %}class="patron" style="background-color:#{{targets[loop.index-1].name_color}}"{% endif %}>{{targets[loop.index-1].user_name}}</span></a></td>
</tr>
{% endfor %}
</table>

View File

@ -28,17 +28,6 @@
{{v.css | safe}}
</style>
{% endif %}
{% if v.earlylife %}
<style>
.nav-item .text-small.font-weight-bold::before {
content: "((("
}
.nav-item .text-small.font-weight-bold::after {
content: ")))"
}
</style>
{% endif %}
{% else %}
<style>:root{--primary:#{{DEFAULT_COLOR}}</style>
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
@ -289,7 +278,8 @@
<img alt="site banner" src="{{banner}}" width="100%">
{% else %}
{% if SITE_NAME == 'PCM' %}
{% set banner = 'banners/halloween.webp' | asset_siteimg %}
{% set path = "assets/images/" + SITE_NAME + "/banners" %}
{% set banner = "/" + path + "/" + listdir('files/' + path)|max + '?v=1' %}
{% else %}
{% set banner = 'banner.webp' | asset_siteimg %}
{% endif %}

View File

@ -4,7 +4,7 @@
#emojiTabs {height: 80%;}
@media (max-width: 650px) {
#emojiTabs {height: 100%;}
#emojiModalInternalDivIDK {margin-top: 0 !important; margin-bottom: 0 !important; padding-top: 0 !important; padding-bottom: 0 !important;}
#emojiModalInternalDivIDK {margin-top: 0 !important; margin-bottom: 0 !important; padding-top: 3rem !important; padding-bottom: 0 !important;}
#emoji-modal-tabs-container {
overflow-x: auto;
@ -20,7 +20,7 @@
}
}
</style>
<div id="emojiModalInternalDivIDK" class="modal-dialog modal-dialog-scrollable modal-dialog-centered p-2 py-5 emoji-modal" role="document">
<div id="emojiModalInternalDivIDK" class="modal-dialog modal-dialog-scrollable modal-dialog-centered emoji-modal" role="document">
<div class="modal-content" id="emojiTabs">
<div class="modal-header">
<div id="emoji-modal-tabs-container">

View File

@ -1,7 +1,7 @@
{% extends "default.html" %}
{% block title %}
<title>Max file size is 8 MB (16 MB for paypigs)</title>
<title>Max image/audio size is 8 MB (16 MB for paypigs)</title>
{% endblock %}
{% block pagetype %}error-413{% endblock %}
@ -12,9 +12,9 @@
<div class="text-center px-3 my-8">
<img alt=":#marseyretard:" loading="lazy" src="/e/marseychonker2.webp">
<pre></pre>
<h1 class="h5">Max file size is 8 MB (16 MB for paypigs)</h1>
<h1 class="h5">Max image/audio size is 8 MB (16 MB for paypigs)</h1>
<div><a href="/" class="btn btn-primary">Go to frontpage</a></div>
</div>
</div>
</div>
{% endblock %}
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends "default.html" %}
{% block title %}
<title>Max video size is 32 MB (64 MB for paypigs)</title>
{% endblock %}
{% block pagetype %}error-414{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-10 col-md-5">
<div class="text-center px-3 my-8">
<img alt=":#marseyretard:" loading="lazy" src="/e/marseychonker2.webp">
<pre></pre>
<h1 class="h5">Max video size is 32 MB (64 MB for paypigs)</h1>
<div><a href="/" class="btn btn-primary">Go to frontpage</a></div>
</div>
</div>
</div>
{% endblock %}

View File

@ -68,14 +68,16 @@
<style>
{% if g.webview %}
@media (min-width: 480px) {
{% elif SITE_NAME == 'WPD' %}
@media (min-width: 1000px) {
{% else %}
@media (min-width: 380px) {
{% endif %}
#logo {
width: 100px;
margin-left: 0.5rem !important;
}
}
{% endif %}
</style>
<div id="logo-container" class="flex-grow-1 logo-container">
<a href="/">
@ -222,7 +224,7 @@
{%- endif %}
</div>
<div class="text-left pl-2">
<div style="color: #{{v.name_color}}" class="text-small font-weight-bold"><span id="header--username" {% if v.patron %}class="patron" style="background-color:#{{v.name_color}}"{% endif %}>{{v.username}}</span></div>
<div style="color: #{{v.name_color}}" class="text-small font-weight-bold"><span id="header--username" {% if v.patron %}class="patron" style="background-color:#{{v.name_color}}"{% endif %}>{{v.user_name}}</span></div>
<div class="header--currency"><img alt="coins" class="mr-1 ml-1" data-bs-toggle="tooltip" data-bs-placement="bottom" src="{{'coins.webp' | asset_siteimg}}" title="coins" aria-label="coins"><span id="user-coins-amount">{{v.coins}}</span>{% if not FEATURES['PROCOINS'] %} Coin{{ help.plural(v.coins) }}{% endif %}</div>
{% if FEATURES['PROCOINS'] %}
<div class="header--currency"><img alt="marseybux" class="mr-1 ml-1" data-bs-toggle="tooltip" data-bs-placement="bottom" src="/i/marseybux.webp?v=2000" title="Marseybux" aria-label="Marseybux"><span id="user-bux-amount">{{v.procoins}}</span></div>

View File

@ -6,19 +6,17 @@
<pre class="d-none d-md-inline-block"></pre>
<div id="leaderboard-contents" style="text-align: center; margin-bottom: 1.5rem; font-size: 1.2rem;">
<a href="#leaderboard-coins">Coins</a> &bull;
<a href="#leaderboard-spent">Spent in Shop</a> &bull;
<a href="#leaderboard-spent">Spent in shop</a> &bull;
<a href="#leaderboard-truescore">Truescore</a> &bull;
<a href="#leaderboard-followers">Followers</a> &bull;
<a href="#leaderboard-posts">Posts</a> &bull;
<a href="#leaderboard-comments">Comments</a> &bull;
<a href="#leaderboard-awards">Awards</a> &bull;
<a href="#leaderboard-downvotes">Downvotes</a> &bull;
<a href="#leaderboard-badges">Badges</a> &bull;
{% if users12 %}<a href="#leaderboard-marseys">Marseys</a> &bull; {% endif %}
{% if users13 %}<a href="#leaderboard-upgiven">Upvotes Given</a> &bull; {% endif %}
<a href="#leaderboard-blocked">Blocked</a> &bull;
<a href="#leaderboard-owned-hats">Owned Hats</a> &bull;
<a href="#leaderboard-designed-hats">Designed Hats</a>
<a href="#leaderboard-owned-hats">Owned hats</a> &bull;
<a href="#leaderboard-designed-hats">Designed hats</a>
</div>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-coins">Top 25 by coins</a></h5>
@ -234,39 +232,6 @@
{% endif %}
</table>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-downvotes">Top 25 by received downvotes</a></h5>
<div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white">
<tr>
<th>#</th>
<th>Name</th>
<th>Downvotes</th>
</tr>
</thead>
<tbody>
{% for user, num in users9 %}
<tr {% if v.id == user.id %}class="self"{% endif %}>
<td>{{loop.index}}</td>
<td>{% include "user_in_table.html" %}</td>
<td>{{"{:,}".format(num)}}</td>
</tr>
{% endfor %}
{% if pos9 and (pos9[0] > 25 or not pos9[1]) %}
<tr style="border-top:2px solid var(--primary)">
<td>{{pos9[0]}}</td>
<td>
{% with user=v %}
{% include "user_in_table.html" %}
{% endwith %}
</td>
<td>{{"{:,}".format(pos9[1])}}</td>
</tr>
{% endif %}
</tbody>
</table>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-badges">Top 25 by badges</a></h5>
<div class="overflow-x-auto"><table class="table table-striped mb-5">
@ -303,7 +268,7 @@
{% if users12 %}
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-marseys">Top 25 by marseys made</a></h5>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-marseys">Top 25 by Marseys made</a></h5>
<div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white">
@ -336,41 +301,7 @@
</table>
{% endif %}
{% if users13 %}
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-upgiven">Top 25 by upvotes given</a></h5>
<div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white">
<tr>
<th>#</th>
<th>Name</th>
<th>Upvotes</th>
</tr>
</thead>
<tbody>
{% for user, num in users13 %}
<tr {% if v.id == user.id %}class="self"{% endif %}>
<td>{{loop.index}}</td>
<td>{% include "user_in_table.html" %}</td>
<td>{{"{:,}".format(num)}}</td>
</tr>
{% endfor %}
{% if pos13 and (pos13[0] > 25 or not pos13[1]) %}
<tr style="border-top:2px solid var(--primary)">
<td>{{pos13[0]}}</td>
<td>
{% with user=v %}
{% include "user_in_table.html" %}
{% endwith %}
</td>
<td>{{"{:,}".format(pos13[1])}}</td>
</tr>
{% endif %}
</tbody>
</table>
{% endif %}
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-blocked">Top 25 Most Blocked</a></h5>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-blocked">Top 25 most blocked</a></h5>
<div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white">
@ -401,7 +332,7 @@
</table>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-owned-hats">Top 25 by Owned Hats</a></h5>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-owned-hats">Top 25 by owned hats</a></h5>
<div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white">
@ -431,7 +362,7 @@
{% endif %}
</table>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-designed-hats">Top 25 by Designed Hats</a></h5>
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-designed-hats">Top 25 by designed hats</a></h5>
<div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white">

View File

@ -19,17 +19,6 @@
{{v.css | safe}}
</style>
{% endif %}
{% if v.earlylife %}
<style>
.nav-item .text-small.font-weight-bold::before {
content: "((("
}
.nav-item .text-small.font-weight-bold::after {
content: ")))"
}
</style>
{% endif %}
{% else %}
<style>:root{--primary:#{{DEFAULT_COLOR}}</style>
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
@ -162,4 +151,4 @@
<script defer src="{{'js/clipboard.js' | asset}}"></script>
{% endblock %}
{% endblock %}

View File

@ -46,17 +46,6 @@
{{v.css | safe}}
</style>
{% endif %}
{% if v.earlylife %}
<style>
.nav-item .text-small.font-weight-bold::before {
content: "((("
}
.nav-item .text-small.font-weight-bold::after {
content: ")))"
}
</style>
{% endif %}
</head>
<body id="settings" {% if SITE_NAME == 'rDrama' and v and (v.is_banned or v.agendaposter) %}style="overflow-x: hidden;background:url(/assets/images/backgrounds/anime/1.webp?v=3) center center fixed; background-color: var(--background)"{% elif v and v.background %}style="overflow-x: hidden;background:url(/assets/images/backgrounds/{{v.background}}?v=3) center center fixed; background-color: var(--background){% if 'anime' not in v.background %};background-size: cover{% endif %}"{% endif %}>
@ -263,4 +252,4 @@
</body>
</html>
</html>

View File

@ -23,9 +23,8 @@
<a class="btn btn-primary btn-block" href="/create_hole">CREATE {{HOLE_NAME|upper}}</a>
{%- endif %}
<a class="btn btn-primary btn-block" href="/holes">BROWSE {{HOLE_NAME|upper}}S</a>
<a class="btn btn-primary btn-block mt-5" href="/">
<span style="display: block;font-size: 1.35rem;">STREAM LIST</span>
<span style="display: block;font-size: 0.85rem;">Coming Sometime 2022</span>
<a class="btn btn-primary btn-block mt-5" href="/live">
<span style="display: block; font-size: 1.5rem; line-height: 2;">LIVE LIST</span>
</a>
<a class="btn btn-primary btn-block" href="/post/4103">BUGS/SUGGESTIONS MEGATHREAD</a>
<a class="btn btn-primary btn-block" href="/post/9694" >OFFICIAL CONSPIRACY THEORY THREAD</a>

View File

@ -112,7 +112,7 @@
required="">
<div class="custom-control custom-checkbox mt-4">
<input autocomplete="off" type="checkbox" class="custom-control-input" id="termsCheck" required>
<label class="custom-control-label terms" for="termsCheck">I accept the <a href="/logged_out/sidebar">rules</a></label>
<label class="custom-control-label terms" for="termsCheck">I accept the <a href="/sidebar">rules</a></label>
</div>
{% if hcaptcha %}

View File

@ -44,17 +44,6 @@
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
<link rel="stylesheet" href="{{('css/'~DEFAULT_THEME~'.css') | asset}}">
{% endif %}
{% if v.earlylife %}
<style>
.nav-item .text-small.font-weight-bold::before {
content: "((("
}
.nav-item .text-small.font-weight-bold::after {
content: ")))"
}
</style>
{% endif %}
{% endblock %}
</head>

View File

@ -5,5 +5,5 @@
<img class="profile-pic-20-hat hat" loading="lazy" src="{{user.hat_active}}?h=7" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{user.hat_tooltip(v)}}">
{%- endif %}
</div>
<span {% if user.patron %}class="patron" style="background-color:#{{user.name_color}}"{% endif %}>{{user.username}}</span>
</a>
<span {% if user.patron %}class="patron" style="background-color:#{{user.name_color}}"{% endif %}>{{user.user_name}}</span>
</a>

View File

@ -67,7 +67,7 @@
</h5>
{% endif %}
<div class="d-flex align-items-center mt-1 mb-2">
<h1 class="font-weight-bolder h3 my-0 mr-2" id="profile--name" style="color: #{{u.name_color}}"><span {% if u.patron %}class="patron" style="background-color:#{{u.name_color}}"{% endif %}>{{u.username}}</span></h1>
<h1 class="font-weight-bolder h3 my-0 mr-2" id="profile--name" style="color: #{{u.name_color}}"><span {% if u.patron %}class="patron" style="background-color:#{{u.name_color}}"{% endif %}>{{u.user_name}}</span></h1>
{% if u.username != u.original_username %}
<span id="profile--origname">
@ -445,7 +445,7 @@
<h5 class="text-primary" id="profile-mobile--banned">SHADOWBANNED USER{% if u.ban_reason %}: {{u.ban_reason | safe}}{% endif %} (by <a href="/@{{u.shadowbanned}}">@{{u.shadowbanned}}</a>)</h5>
{% endif %}
<h1 class="h5 d-inline-block" id="profile-mobile--name" style="color: #{{u.name_color}}"><span {% if u.patron %}class="patron" style="background-color:#{{u.name_color}}"{% endif %}>{{u.username}}</span></h1>
<h1 class="h5 d-inline-block" id="profile-mobile--name" style="color: #{{u.name_color}}"><span {% if u.patron %}class="patron" style="background-color:#{{u.name_color}}"{% endif %}>{{u.user_name}}</span></h1>
{% if u.username != u.original_username %}
<span id="profile-mobile--origname">

View File

@ -5,7 +5,7 @@ from files.__main__ import app
# these tests require `docker-compose up` first
def test_rules():
response = app.test_client().get("/logged_out/rules")
response = app.test_client().get("/sidebar")
assert response.status_code == 200
assert response.text.startswith("<!DOCTYPE html>")

View File

@ -14,10 +14,10 @@ server {
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://127.0.0.1:5001/socket.io;
proxy_pass http://localhost:5001/socket.io;
}
location /chat {
proxy_pass http://127.0.0.1:5001/chat;
proxy_pass http://localhost:5001/chat;
}
location /images/ {

1372
redis.conf

File diff suppressed because it is too large Load Diff

View File

@ -166,8 +166,7 @@ CREATE TABLE public.award_relationships (
comment_id integer,
kind character varying(20) NOT NULL,
awarded_utc integer,
created_utc integer,
granted_by integer
created_utc integer
);
@ -561,6 +560,19 @@ CREATE TABLE public.marseys (
);
--
-- Name: media; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.media (
kind character varying(5) NOT NULL,
filename character varying(55) NOT NULL,
user_id integer NOT NULL,
created_utc integer NOT NULL,
size integer NOT NULL
);
--
-- Name: modactions; Type: TABLE; Schema: public; Owner: -
--
@ -1319,6 +1331,14 @@ ALTER TABLE ONLY public.marseys
ADD CONSTRAINT marseys_pkey PRIMARY KEY (name);
--
-- Name: media media_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.media
ADD CONSTRAINT media_pkey PRIMARY KEY (kind, filename);
--
-- Name: modactions modactions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@ -2080,14 +2100,6 @@ ALTER TABLE ONLY public.award_relationships
ADD CONSTRAINT award_comment_fkey FOREIGN KEY (comment_id) REFERENCES public.comments(id);
--
-- Name: award_relationships award_granted_by_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.award_relationships
ADD CONSTRAINT award_granted_by_fkey FOREIGN KEY (granted_by) REFERENCES public.users(id);
--
-- Name: award_relationships award_submission_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@ -2352,6 +2364,14 @@ ALTER TABLE ONLY public.marseys
ADD CONSTRAINT marsey_submitter_fkey FOREIGN KEY (submitter_id) REFERENCES public.users(id);
--
-- Name: media media_user_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.media
ADD CONSTRAINT media_user_fkey FOREIGN KEY (user_id) REFERENCES public.users(id);
--
-- Name: mods mod_sub_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--

View File

@ -283,6 +283,7 @@ INSERT INTO public.hat_defs VALUES (781, 'BTC', 'Only wear this if you''re worth
INSERT INTO public.hat_defs VALUES (723, 'Hohol', 'Мій предок :)', 2, 500, NULL, 1663892328);
INSERT INTO public.hat_defs VALUES (750, 'Cave Man', 'UNGA BUNGA UNGA BUNGA OOO OOO', 2, 500, NULL, 1664595865);
INSERT INTO public.hat_defs VALUES (753, 'Doom Guy', 'RIP AND TEAR', 2, 500, NULL, 1664595933);
@ -938,7 +939,7 @@ INSERT INTO public.hat_defs VALUES (504, 'Iron Crown of Lombardy', 'This isn''t
-- Name: hat_defs_id_seq; Type: SEQUENCE SET; Schema: public; Owner: -
--
SELECT pg_catalog.setval('public.hat_defs_id_seq', 802, true);
SELECT pg_catalog.setval('public.hat_defs_id_seq', 803, true);
--
@ -1202,6 +1203,8 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseycapitalistmanlet',2,'money top hat rich landlord cigar llm tophat',NULL),
('marseycapy',2,'capybara rodent aevann happy cute',NULL),
('marseycapy2022',2,'aevann caypbara new year party celebration',NULL),
('marseycapyautism',2,'capy aevann autism hat patient capybara',1665095792),
('marseycapyautismchad',2,'capy aevann autism hat patient capybara chad gigachad',1665098772),
('marseycapybigbrain',2,'capybara aevann smart codecel brain',NULL),
('marseycapyblackface',2,'racist minstrelsy bowtie racism capybara aevann',NULL),
('marseycapyblowkiss',2,'capybara rodent aevann happy cute love',NULL),
@ -2586,6 +2589,9 @@ INSERT INTO public.marseys (name, author_id, tags, created_utc) VALUES
('marseyvibing',2,'animated bopping vibe jam dancing headbang music rainbow dance',NULL),
('marseyvietnam',2,'army born to kill soldier war',NULL),
('marseyvirus',2,'phage infect infection plagued',NULL),
('marseyvore',2,'eating cannibalism cannibalize fetish kinky digest trapped letmeout',1665074856),
('marseyvore2',2,'eating marcus cannibalize cannibalism fetish kinky',1665074817),
('marseyvorezombiewolf',2,'furry furfag food eat yum degenerate fetish hungry',1665041705),
('marseyw',2,'win winner dub',NULL),
('marseywagie',2,'crypto rightoid ancap poor wagecuck mcdonalds maccas reaction',NULL),
('marseywait',2,'time watch wait waiting bored',NULL),

File diff suppressed because one or more lines are too long

View File

@ -1,5 +0,0 @@
alter table award_relationships add column granted_by int;
ALTER TABLE ONLY public.award_relationships
ADD CONSTRAINT award_granted_by_fkey FOREIGN KEY (granted_by) REFERENCES public.users(id);
update award_relationships set granted_by=1 where granted=true;
alter table award_relationships drop column granted;

View File

@ -0,0 +1,13 @@
CREATE TABLE public.media (
kind character varying(5) NOT NULL,
filename character varying(55) NOT NULL,
user_id Integer NOT NULL,
created_utc integer NOT NULL,
size integer NOT NULL
);
ALTER TABLE ONLY public.media
ADD CONSTRAINT media_pkey PRIMARY KEY (kind, filename);
ALTER TABLE ONLY public.media
ADD CONSTRAINT media_user_fkey FOREIGN KEY (user_id) REFERENCES public.users(id);

View File

@ -1,7 +1,4 @@
# locale-gen "en_US.UTF-8"
# update-locale LANG=en_US.utf8
# update-locale LC_ALL=en_US.utf8
# reboot
apt -y update
apt -y upgrade
apt -y install git redis-server python3-pip ffmpeg imagemagick tmux nginx snapd ufw gpg-agent htop nano