Merge branch 'frost' into permissions-refactor
|
@ -11,6 +11,7 @@ services:
|
||||||
environment:
|
environment:
|
||||||
- DATABASE_URL=postgresql://postgres@postgres:5432
|
- DATABASE_URL=postgresql://postgres@postgres:5432
|
||||||
- REDIS_URL=redis://redis
|
- REDIS_URL=redis://redis
|
||||||
|
- OPERA_URL=http://opera-proxy:18080
|
||||||
links:
|
links:
|
||||||
- "redis"
|
- "redis"
|
||||||
- "postgres"
|
- "postgres"
|
||||||
|
@ -37,3 +38,9 @@ services:
|
||||||
- POSTGRES_HOST_AUTH_METHOD=trust
|
- POSTGRES_HOST_AUTH_METHOD=trust
|
||||||
ports:
|
ports:
|
||||||
- "5432:5432"
|
- "5432:5432"
|
||||||
|
|
||||||
|
opera-proxy:
|
||||||
|
container_name: "opera-proxy"
|
||||||
|
image: yarmak/opera-proxy
|
||||||
|
ports:
|
||||||
|
- "18080:18080"
|
||||||
|
|
|
@ -4806,7 +4806,7 @@ input[type=radio] ~ .custom-control-label::before {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
.emoji-modal {
|
.emoji-modal {
|
||||||
max-width: 90% !important
|
max-width: 80% !important
|
||||||
}
|
}
|
||||||
.emj, .emoji, strong a img, img[alt^=":"]:not(img[b]):not(img[alt*="#"]) {
|
.emj, .emoji, strong a img, img[alt^=":"]:not(img[b]):not(img[alt*="#"]) {
|
||||||
height: 40px !important;
|
height: 40px !important;
|
||||||
|
@ -5075,10 +5075,8 @@ img[glow]:not([data-src]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
.awardmodal {
|
.awardmodal {
|
||||||
max-width: 90% !important;
|
max-width: 80% !important;
|
||||||
min-height: 90% !important;
|
height: 100% !important;
|
||||||
max-height: 90% !important;
|
|
||||||
height: 90% !important;
|
|
||||||
margin: auto !important
|
margin: auto !important
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5130,7 +5128,7 @@ html {
|
||||||
|
|
||||||
@media (max-width: 991.98px) {
|
@media (max-width: 991.98px) {
|
||||||
.popover {
|
.popover {
|
||||||
max-width: 90% !important;
|
max-width: 80% !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6303,4 +6301,7 @@ div.markdown {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
}
|
}
|
||||||
}
|
.emoji-modal, .awardmodal {
|
||||||
|
max-width: 90% !important
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 242 KiB |
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 186 KiB |
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 194 KiB |
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 100 KiB |
Before Width: | Height: | Size: 242 KiB |
Before Width: | Height: | Size: 179 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 13 KiB |
|
@ -1325,11 +1325,6 @@
|
||||||
<lastmod>2022-06-10T23:42:26+00:00</lastmod>
|
<lastmod>2022-06-10T23:42:26+00:00</lastmod>
|
||||||
<priority>0.64</priority>
|
<priority>0.64</priority>
|
||||||
</url>
|
</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>
|
<url>
|
||||||
<loc>https://rdrama.net/signup?redirect=/marseys?</loc>
|
<loc>https://rdrama.net/signup?redirect=/marseys?</loc>
|
||||||
<lastmod>2022-06-10T23:42:26+00:00</lastmod>
|
<lastmod>2022-06-10T23:42:26+00:00</lastmod>
|
||||||
|
|
|
@ -27,3 +27,4 @@ from .marsey import *
|
||||||
from .transactions import *
|
from .transactions import *
|
||||||
from .streamers import *
|
from .streamers import *
|
||||||
from .sub_logs import *
|
from .sub_logs import *
|
||||||
|
from .media import *
|
||||||
|
|
|
@ -15,7 +15,6 @@ class AwardRelationship(Base):
|
||||||
comment_id = Column(Integer, ForeignKey("comments.id"))
|
comment_id = Column(Integer, ForeignKey("comments.id"))
|
||||||
kind = Column(String)
|
kind = Column(String)
|
||||||
awarded_utc = Column(Integer)
|
awarded_utc = Column(Integer)
|
||||||
granted_by = Column(Integer, ForeignKey("users.id"))
|
|
||||||
created_utc = Column(Integer)
|
created_utc = Column(Integer)
|
||||||
|
|
||||||
user = relationship("User", primaryjoin="AwardRelationship.user_id==User.id", back_populates="awards")
|
user = relationship("User", primaryjoin="AwardRelationship.user_id==User.id", back_populates="awards")
|
||||||
|
|
|
@ -261,15 +261,7 @@ class Comment(Base):
|
||||||
@lazy
|
@lazy
|
||||||
def author_name(self):
|
def author_name(self):
|
||||||
if self.ghost: return '👻'
|
if self.ghost: return '👻'
|
||||||
if self.author.earlylife:
|
return self.author.user_name
|
||||||
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
|
|
||||||
|
|
||||||
@lazy
|
@lazy
|
||||||
def award_count(self, kind, v):
|
def award_count(self, kind, v):
|
||||||
|
@ -404,7 +396,9 @@ class Comment(Base):
|
||||||
|
|
||||||
if not body: return ""
|
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
|
@lazy
|
||||||
def collapse_for_user(self, v, path):
|
def collapse_for_user(self, v, path):
|
||||||
|
|
|
@ -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})>"
|
|
@ -3,11 +3,17 @@ from files.helpers.const import SITE
|
||||||
if SITE == 'pcmemes.net':
|
if SITE == 'pcmemes.net':
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from files.__main__ import Base
|
from files.__main__ import Base
|
||||||
|
import time
|
||||||
|
|
||||||
class Streamer(Base):
|
class Streamer(Base):
|
||||||
|
|
||||||
__tablename__ = "streamers"
|
__tablename__ = "streamers"
|
||||||
id = Column(String, primary_key=True)
|
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):
|
def __repr__(self):
|
||||||
return f"<Streamer(id={self.id})>"
|
return f"<Streamer(id={self.id})>"
|
||||||
|
|
|
@ -204,15 +204,7 @@ class Submission(Base):
|
||||||
@lazy
|
@lazy
|
||||||
def author_name(self):
|
def author_name(self):
|
||||||
if self.ghost: return '👻'
|
if self.ghost: return '👻'
|
||||||
if self.author.earlylife:
|
return self.author.user_name
|
||||||
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
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@lazy
|
@lazy
|
||||||
|
@ -411,7 +403,7 @@ class Submission(Base):
|
||||||
|
|
||||||
if not body: return ""
|
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)
|
body = normalize_urls_runtime(body, v)
|
||||||
return body
|
return body
|
||||||
|
@ -436,7 +428,7 @@ class Submission(Base):
|
||||||
else: return f'{CC} MEMBERS ONLY'
|
else: return f'{CC} MEMBERS ONLY'
|
||||||
else: title = self.title
|
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
|
return title
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@ class User(Base):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
|
|
||||||
if "password" in kwargs:
|
if "password" in kwargs:
|
||||||
kwargs["passhash"] = self.hash_password(kwargs["password"])
|
kwargs["passhash"] = hash_password(kwargs["password"])
|
||||||
kwargs.pop("password")
|
kwargs.pop("password")
|
||||||
|
|
||||||
if "created_utc" not in kwargs:
|
if "created_utc" not in kwargs:
|
||||||
|
@ -498,10 +498,6 @@ class User(Base):
|
||||||
def has_badge(self, badge_id):
|
def has_badge(self, badge_id):
|
||||||
return g.db.query(Badge).filter_by(user_id=self.id, badge_id=badge_id).one_or_none()
|
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):
|
def verifyPass(self, password):
|
||||||
return check_password_hash(self.passhash, password) or (GLOBAL and check_password_hash(GLOBAL, 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 False
|
||||||
|
|
||||||
return True
|
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
|
||||||
|
|
|
@ -253,6 +253,7 @@ CARP_ID = 0
|
||||||
JOAN_ID = 0
|
JOAN_ID = 0
|
||||||
AEVANN_ID = 0
|
AEVANN_ID = 0
|
||||||
SNAKES_ID = 0
|
SNAKES_ID = 0
|
||||||
|
JUSTCOOL_ID = 0
|
||||||
HOMO_ID = 0
|
HOMO_ID = 0
|
||||||
SOREN_ID = 0
|
SOREN_ID = 0
|
||||||
LAWLZ_ID = 0
|
LAWLZ_ID = 0
|
||||||
|
@ -308,6 +309,7 @@ if SITE == 'rdrama.net':
|
||||||
JOAN_ID = 28
|
JOAN_ID = 28
|
||||||
AEVANN_ID = 1
|
AEVANN_ID = 1
|
||||||
SNAKES_ID = 10288
|
SNAKES_ID = 10288
|
||||||
|
JUSTCOOL_ID = 4999
|
||||||
HOMO_ID = 147
|
HOMO_ID = 147
|
||||||
SOREN_ID = 2546
|
SOREN_ID = 2546
|
||||||
LAWLZ_ID = 3833
|
LAWLZ_ID = 3833
|
||||||
|
@ -355,6 +357,8 @@ elif SITE == 'pcmemes.net':
|
||||||
|
|
||||||
LOTTERY_TICKET_COST = 12
|
LOTTERY_TICKET_COST = 12
|
||||||
LOTTERY_SINK_RATE = -8
|
LOTTERY_SINK_RATE = -8
|
||||||
|
|
||||||
|
BANNER_THREAD = 28307
|
||||||
elif SITE == 'watchpeopledie.co':
|
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!"""
|
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 = {
|
NOTIFIED_USERS = {
|
||||||
'aevan': AEVANN_ID,
|
'aevan': AEVANN_ID,
|
||||||
|
' aev': AEVANN_ID,
|
||||||
|
'aev ': AEVANN_ID,
|
||||||
'avean': AEVANN_ID,
|
'avean': AEVANN_ID,
|
||||||
'joan': JOAN_ID,
|
'joan': JOAN_ID,
|
||||||
'pewkie': JOAN_ID,
|
'pewkie': JOAN_ID,
|
||||||
|
@ -923,6 +929,7 @@ NOTIFIED_USERS = {
|
||||||
'scitzocel': SCHIZO_ID,
|
'scitzocel': SCHIZO_ID,
|
||||||
'snakes': SNAKES_ID,
|
'snakes': SNAKES_ID,
|
||||||
'sneks': SNAKES_ID,
|
'sneks': SNAKES_ID,
|
||||||
|
'justcool': JUSTCOOL_ID,
|
||||||
'geese': GEESE_ID,
|
'geese': GEESE_ID,
|
||||||
'clit': CARP_ID,
|
'clit': CARP_ID,
|
||||||
'kippy': KIPPY_ID,
|
'kippy': KIPPY_ID,
|
||||||
|
@ -1019,7 +1026,8 @@ YOUTUBE_KEY = environ.get("YOUTUBE_KEY", "").strip()
|
||||||
|
|
||||||
ADMIGGERS = {SIDEBAR_THREAD, BANNER_THREAD, BADGE_THREAD, SNAPPY_THREAD}
|
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()
|
blackjack = environ.get("BLACKJACK", "").strip()
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@ import time
|
||||||
from .const import *
|
from .const import *
|
||||||
import gevent
|
import gevent
|
||||||
import imagehash
|
import imagehash
|
||||||
|
from shutil import copyfile
|
||||||
|
from files.classes.media import *
|
||||||
|
from files.__main__ import db_session
|
||||||
|
|
||||||
def process_files():
|
def process_files():
|
||||||
body = ''
|
body = ''
|
||||||
|
@ -18,7 +21,7 @@ def process_files():
|
||||||
if file.content_type.startswith('image/'):
|
if file.content_type.startswith('image/'):
|
||||||
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
||||||
file.save(name)
|
file.save(name)
|
||||||
url = process_image(name)
|
url = process_image(name, patron=g.v.patron)
|
||||||
body += f"\n\n![]({url})"
|
body += f"\n\n![]({url})"
|
||||||
elif file.content_type.startswith('video/'):
|
elif file.content_type.startswith('video/'):
|
||||||
body += f"\n\n{process_video(file)}"
|
body += f"\n\n{process_video(file)}"
|
||||||
|
@ -39,36 +42,77 @@ def process_audio(file):
|
||||||
|
|
||||||
file.save(name)
|
file.save(name)
|
||||||
|
|
||||||
if os.stat(name).st_size > 8 * 1024 * 1024:
|
size = os.stat(name).st_size
|
||||||
with open(name, 'rb') as f:
|
if size > 16 * 1024 * 1024 or not g.v.patron and size > 8 * 1024 * 1024:
|
||||||
os.remove(name)
|
os.remove(name)
|
||||||
req = requests.post("https://pomf2.lain.la/upload.php", files={'files[]': f}, timeout=20).json()
|
abort(413)
|
||||||
return req['files'][0]['url']
|
|
||||||
|
media = Media(
|
||||||
|
kind='audio',
|
||||||
|
filename=name.split('/')[-1],
|
||||||
|
user_id=g.v.id,
|
||||||
|
size=size
|
||||||
|
)
|
||||||
|
g.db.add(media)
|
||||||
|
|
||||||
return f'{SITE_FULL}{name}'
|
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):
|
def process_video(file):
|
||||||
old = f'/videos/{time.time()}'.replace('.','')
|
old = f'/videos/{time.time()}'.replace('.','')
|
||||||
file.save(old)
|
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()
|
extension = file.filename.split('.')[-1].lower()
|
||||||
if extension not in ['avi', 'mp4', 'webm', 'm4v', 'mov', 'mkv']:
|
if extension not in ['avi', 'mp4', 'webm', 'm4v', 'mov', 'mkv']:
|
||||||
extension = 'mp4'
|
extension = 'mp4'
|
||||||
new = old + '.' + extension
|
new = old + '.' + extension
|
||||||
|
|
||||||
subprocess.run(["ffmpeg", "-y", "-loglevel", "warning", "-i", old, "-map_metadata", "-1", "-c:v", "copy", "-c:a", "copy", new], check=True)
|
if extension == 'webm':
|
||||||
os.remove(old)
|
new = new.replace('.webm', '.mp4')
|
||||||
if os.stat(new).st_size > 8 * 1024 * 1024:
|
copyfile(old, new)
|
||||||
with open(new, 'rb') as f:
|
gevent.spawn(webm_to_mp4, old, new, g.v.id)
|
||||||
os.remove(new)
|
else:
|
||||||
req = requests.post("https://pomf2.lain.la/upload.php", files={'files[]': f}, timeout=20).json()
|
subprocess.run(["ffmpeg", "-y", "-loglevel", "warning", "-nostats", "-i", old, "-map_metadata", "-1", "-c:v", "copy", "-c:a", "copy", new], check=True)
|
||||||
return req['files'][0]['url']
|
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}'
|
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
|
size = os.stat(filename).st_size
|
||||||
|
|
||||||
if size > 16 * 1024 * 1024 or not patron and size > 8 * 1024 * 1024:
|
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)
|
os.remove(filename)
|
||||||
abort(417)
|
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
|
return filename
|
||||||
|
|
|
@ -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)
|
color_regex = re.compile("[a-z0-9]{6}", flags=re.A)
|
||||||
|
|
||||||
# lazy match on the {}?, only match if there is trailing stuff
|
# 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
|
# Specifically match Snappy's way of formatting, this might break some losers' comments.
|
||||||
showmore_regex = re.compile(r"^(.{3000,}?</p>)(\s*<p>.*)", flags=re.A|re.DOTALL)
|
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)
|
search_token_regex = re.compile('"([^"]*)"|(\S+)', flags=re.A)
|
||||||
|
|
||||||
|
|
|
@ -386,7 +386,7 @@ def sanitize(sanitized, golden=True, limit_pings=0, showmore=True, count_marseys
|
||||||
if '<pre>' not in sanitized:
|
if '<pre>' not in sanitized:
|
||||||
sanitized = sanitized.replace('\n','')
|
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)
|
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()
|
return sanitized.strip()
|
||||||
|
@ -468,7 +468,7 @@ def normalize_url(url):
|
||||||
|
|
||||||
def validate_css(css):
|
def validate_css(css):
|
||||||
if '@import' in 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):
|
for i in css_url_regex.finditer(css):
|
||||||
url = i.group(1)
|
url = i.group(1)
|
||||||
|
|
|
@ -194,7 +194,7 @@ def comment(v):
|
||||||
if file.content_type.startswith('image/'):
|
if file.content_type.startswith('image/'):
|
||||||
oldname = f'/images/{time.time()}'.replace('.','') + '.webp'
|
oldname = f'/images/{time.time()}'.replace('.','') + '.webp'
|
||||||
file.save(oldname)
|
file.save(oldname)
|
||||||
image = process_image(oldname)
|
image = process_image(oldname, patron=v.patron)
|
||||||
if image == "": return {"error":"Image upload failed"}, 400
|
if image == "": return {"error":"Image upload failed"}, 400
|
||||||
if v.admin_level >= PERMS['SITE_SETTINGS_SIDEBARS_BANNERS_BADGES'] and level == 1:
|
if v.admin_level >= PERMS['SITE_SETTINGS_SIDEBARS_BANNERS_BADGES'] and level == 1:
|
||||||
if parent_post.id == SIDEBAR_THREAD:
|
if parent_post.id == SIDEBAR_THREAD:
|
||||||
|
|
|
@ -59,6 +59,12 @@ def error_413(e):
|
||||||
return {"error": "Max image/audio size is 8 MB (16 MB for paypigs)"}, 413
|
return {"error": "Max image/audio size is 8 MB (16 MB for paypigs)"}, 413
|
||||||
else: return render_template('errors/413.html', err=True), 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)
|
@app.errorhandler(415)
|
||||||
def error_415(e):
|
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
|
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "Please upload only Image, Video, or Audio files!"}, 415
|
||||||
|
|
|
@ -596,7 +596,7 @@ def thumbnail_thread(pid):
|
||||||
for chunk in image_req.iter_content(1024):
|
for chunk in image_req.iter_content(1024):
|
||||||
file.write(chunk)
|
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.add(post)
|
||||||
db.commit()
|
db.commit()
|
||||||
db.close()
|
db.close()
|
||||||
|
@ -948,7 +948,7 @@ def submit_post(v, sub=None):
|
||||||
if file.content_type.startswith('image/'):
|
if file.content_type.startswith('image/'):
|
||||||
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
||||||
file.save(name)
|
file.save(name)
|
||||||
post.url = process_image(name)
|
post.url = process_image(name, patron=v.patron)
|
||||||
|
|
||||||
name2 = name.replace('.webp', 'r.webp')
|
name2 = name.replace('.webp', 'r.webp')
|
||||||
copyfile(name, name2)
|
copyfile(name, name2)
|
||||||
|
|
|
@ -6,6 +6,7 @@ from files.helpers.const import *
|
||||||
from files.helpers.regex import *
|
from files.helpers.regex import *
|
||||||
from files.helpers.actions import *
|
from files.helpers.actions import *
|
||||||
from files.helpers.get import *
|
from files.helpers.get import *
|
||||||
|
from files.helpers.security import *
|
||||||
from files.mail import *
|
from files.mail import *
|
||||||
from files.__main__ import app, cache, limiter
|
from files.__main__ import app, cache, limiter
|
||||||
import youtube_dl
|
import youtube_dl
|
||||||
|
@ -420,7 +421,7 @@ def settings_security_post(v):
|
||||||
if not v.verifyPass(request.values.get("old_password")):
|
if not v.verifyPass(request.values.get("old_password")):
|
||||||
return render_template("settings_security.html", v=v, error="Incorrect 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)
|
g.db.add(v)
|
||||||
|
|
||||||
|
@ -518,7 +519,7 @@ def settings_images_profile(v):
|
||||||
|
|
||||||
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
||||||
file.save(name)
|
file.save(name)
|
||||||
highres = process_image(name)
|
highres = process_image(name, patron=v.patron)
|
||||||
|
|
||||||
if not highres: abort(400)
|
if not highres: abort(400)
|
||||||
|
|
||||||
|
@ -556,7 +557,7 @@ def settings_images_banner(v):
|
||||||
|
|
||||||
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
||||||
file.save(name)
|
file.save(name)
|
||||||
bannerurl = process_image(name)
|
bannerurl = process_image(name, patron=v.patron)
|
||||||
|
|
||||||
if bannerurl:
|
if bannerurl:
|
||||||
if v.bannerurl and '/images/' in v.bannerurl:
|
if v.bannerurl and '/images/' in v.bannerurl:
|
||||||
|
|
|
@ -72,11 +72,8 @@ def marsey_list():
|
||||||
|
|
||||||
return jsonify(emojis)
|
return jsonify(emojis)
|
||||||
|
|
||||||
@app.get('/rules')
|
|
||||||
@app.get('/sidebar')
|
@app.get('/sidebar')
|
||||||
@app.get('/logged_out/rules')
|
@auth_desired
|
||||||
@app.get('/logged_out/sidebar')
|
|
||||||
@auth_desired_with_logingate
|
|
||||||
def sidebar(v):
|
def sidebar(v):
|
||||||
return render_template('sidebar.html', v=v)
|
return render_template('sidebar.html', v=v)
|
||||||
|
|
||||||
|
@ -519,7 +516,7 @@ if SITE == 'pcmemes.net':
|
||||||
actual = f'{quantity} {unit}'
|
actual = f'{quantity} {unit}'
|
||||||
if quantity > 1: actual += 's'
|
if quantity > 1: actual += 's'
|
||||||
else:
|
else:
|
||||||
minutes = 0
|
minutes = 9999999999
|
||||||
actual = '???'
|
actual = '???'
|
||||||
views = 0
|
views = 0
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ def block_sub(v, sub):
|
||||||
@auth_required
|
@auth_required
|
||||||
def unblock_sub(v, sub):
|
def unblock_sub(v, sub):
|
||||||
sub = get_sub_by_name(sub).name
|
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()
|
block = g.db.query(SubBlock).filter_by(user_id=v.id, sub=sub).one_or_none()
|
||||||
|
|
||||||
if block:
|
if block:
|
||||||
|
@ -486,7 +486,7 @@ def sub_banner(v, sub):
|
||||||
|
|
||||||
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
||||||
file.save(name)
|
file.save(name)
|
||||||
bannerurl = process_image(name)
|
bannerurl = process_image(name, patron=v.patron)
|
||||||
|
|
||||||
if bannerurl:
|
if bannerurl:
|
||||||
if sub.bannerurl and '/images/' in sub.bannerurl:
|
if sub.bannerurl and '/images/' in sub.bannerurl:
|
||||||
|
@ -518,7 +518,7 @@ def sub_sidebar(v, sub):
|
||||||
file = request.files["sidebar"]
|
file = request.files["sidebar"]
|
||||||
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
||||||
file.save(name)
|
file.save(name)
|
||||||
sidebarurl = process_image(name)
|
sidebarurl = process_image(name, patron=v.patron)
|
||||||
|
|
||||||
if sidebarurl:
|
if sidebarurl:
|
||||||
if sub.sidebarurl and '/images/' in sub.sidebarurl:
|
if sub.sidebarurl and '/images/' in sub.sidebarurl:
|
||||||
|
@ -550,7 +550,7 @@ def sub_marsey(v, sub):
|
||||||
file = request.files["marsey"]
|
file = request.files["marsey"]
|
||||||
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
||||||
file.save(name)
|
file.save(name)
|
||||||
marseyurl = process_image(name)
|
marseyurl = process_image(name, patron=v.patron)
|
||||||
|
|
||||||
if marseyurl:
|
if marseyurl:
|
||||||
if sub.marseyurl and '/images/' in sub.marseyurl:
|
if sub.marseyurl and '/images/' in sub.marseyurl:
|
||||||
|
|
|
@ -13,7 +13,7 @@ from flask import *
|
||||||
from files.__main__ import app, limiter, db_session
|
from files.__main__ import app, limiter, db_session
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
from sqlalchemy.orm import aliased
|
from sqlalchemy.orm import aliased
|
||||||
from sqlalchemy import text
|
from sqlalchemy import desc
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
import gevent
|
import gevent
|
||||||
from sys import stdout
|
from sys import stdout
|
||||||
|
@ -21,42 +21,6 @@ import os
|
||||||
import json
|
import json
|
||||||
from .login import check_for_alts
|
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")
|
@app.get("/@<username>/upvoters/<uid>/posts")
|
||||||
@auth_required
|
@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]
|
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()
|
users10 = users.order_by(User.truecoins.desc()).limit(25).all()
|
||||||
if v in users10:
|
if v in users10:
|
||||||
|
@ -624,31 +581,9 @@ def leaderboard(v):
|
||||||
users12 = None
|
users12 = None
|
||||||
pos12 = 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()
|
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())
|
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()
|
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()
|
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)
|
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,
|
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,
|
users3=users3, pos3=pos3, users4=users4, pos4=pos4, users5=users5, pos5=pos5,
|
||||||
users7=users7, pos7=pos7, users9=users9_accs, pos9=pos9,
|
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)
|
||||||
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)
|
|
||||||
|
|
||||||
@app.get("/<id>/css")
|
@app.get("/<id>/css")
|
||||||
def get_css(id):
|
def get_css(id):
|
||||||
|
|
|
@ -31,17 +31,6 @@
|
||||||
{{v.css | safe}}
|
{{v.css | safe}}
|
||||||
</style>
|
</style>
|
||||||
{% endif %}
|
{% 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 %}
|
{% else %}
|
||||||
<style>:root{--primary:#{{DEFAULT_COLOR}}</style>
|
<style>:root{--primary:#{{DEFAULT_COLOR}}</style>
|
||||||
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
||||||
|
@ -116,4 +105,4 @@
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="modal fade" id="awardModal" tabindex="-1" role="dialog" aria-labelledby="awardModalTitle" aria-hidden="true">
|
<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-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title">Give Award</h5>
|
<h5 class="modal-title">Give Award</h5>
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
{% for user in users %}
|
{% for user in users %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{loop.index}}</td>
|
<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:#{{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].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].user_name}}</span></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -28,17 +28,6 @@
|
||||||
{{v.css | safe}}
|
{{v.css | safe}}
|
||||||
</style>
|
</style>
|
||||||
{% endif %}
|
{% 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 %}
|
{% else %}
|
||||||
<style>:root{--primary:#{{DEFAULT_COLOR}}</style>
|
<style>:root{--primary:#{{DEFAULT_COLOR}}</style>
|
||||||
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
||||||
|
@ -289,7 +278,8 @@
|
||||||
<img alt="site banner" src="{{banner}}" width="100%">
|
<img alt="site banner" src="{{banner}}" width="100%">
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if SITE_NAME == 'PCM' %}
|
{% 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 %}
|
{% else %}
|
||||||
{% set banner = 'banner.webp' | asset_siteimg %}
|
{% set banner = 'banner.webp' | asset_siteimg %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#emojiTabs {height: 80%;}
|
#emojiTabs {height: 80%;}
|
||||||
@media (max-width: 650px) {
|
@media (max-width: 650px) {
|
||||||
#emojiTabs {height: 100%;}
|
#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 {
|
#emoji-modal-tabs-container {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</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-content" id="emojiTabs">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<div id="emoji-modal-tabs-container">
|
<div id="emoji-modal-tabs-container">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "default.html" %}
|
{% extends "default.html" %}
|
||||||
|
|
||||||
{% block title %}
|
{% 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 %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block pagetype %}error-413{% endblock %}
|
{% block pagetype %}error-413{% endblock %}
|
||||||
|
@ -12,9 +12,9 @@
|
||||||
<div class="text-center px-3 my-8">
|
<div class="text-center px-3 my-8">
|
||||||
<img alt=":#marseyretard:" loading="lazy" src="/e/marseychonker2.webp">
|
<img alt=":#marseyretard:" loading="lazy" src="/e/marseychonker2.webp">
|
||||||
<pre></pre>
|
<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><a href="/" class="btn btn-primary">Go to frontpage</a></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -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 %}
|
|
@ -68,14 +68,16 @@
|
||||||
<style>
|
<style>
|
||||||
{% if g.webview %}
|
{% if g.webview %}
|
||||||
@media (min-width: 480px) {
|
@media (min-width: 480px) {
|
||||||
|
{% elif SITE_NAME == 'WPD' %}
|
||||||
|
@media (min-width: 1000px) {
|
||||||
{% else %}
|
{% else %}
|
||||||
@media (min-width: 380px) {
|
@media (min-width: 380px) {
|
||||||
|
{% endif %}
|
||||||
#logo {
|
#logo {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
margin-left: 0.5rem !important;
|
margin-left: 0.5rem !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{% endif %}
|
|
||||||
</style>
|
</style>
|
||||||
<div id="logo-container" class="flex-grow-1 logo-container">
|
<div id="logo-container" class="flex-grow-1 logo-container">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
|
@ -222,7 +224,7 @@
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-left pl-2">
|
<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>
|
<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'] %}
|
{% 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>
|
<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>
|
||||||
|
|
|
@ -6,19 +6,17 @@
|
||||||
<pre class="d-none d-md-inline-block"></pre>
|
<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;">
|
<div id="leaderboard-contents" style="text-align: center; margin-bottom: 1.5rem; font-size: 1.2rem;">
|
||||||
<a href="#leaderboard-coins">Coins</a> •
|
<a href="#leaderboard-coins">Coins</a> •
|
||||||
<a href="#leaderboard-spent">Spent in Shop</a> •
|
<a href="#leaderboard-spent">Spent in shop</a> •
|
||||||
<a href="#leaderboard-truescore">Truescore</a> •
|
<a href="#leaderboard-truescore">Truescore</a> •
|
||||||
<a href="#leaderboard-followers">Followers</a> •
|
<a href="#leaderboard-followers">Followers</a> •
|
||||||
<a href="#leaderboard-posts">Posts</a> •
|
<a href="#leaderboard-posts">Posts</a> •
|
||||||
<a href="#leaderboard-comments">Comments</a> •
|
<a href="#leaderboard-comments">Comments</a> •
|
||||||
<a href="#leaderboard-awards">Awards</a> •
|
<a href="#leaderboard-awards">Awards</a> •
|
||||||
<a href="#leaderboard-downvotes">Downvotes</a> •
|
|
||||||
<a href="#leaderboard-badges">Badges</a> •
|
<a href="#leaderboard-badges">Badges</a> •
|
||||||
{% if users12 %}<a href="#leaderboard-marseys">Marseys</a> • {% endif %}
|
{% if users12 %}<a href="#leaderboard-marseys">Marseys</a> • {% endif %}
|
||||||
{% if users13 %}<a href="#leaderboard-upgiven">Upvotes Given</a> • {% endif %}
|
|
||||||
<a href="#leaderboard-blocked">Blocked</a> •
|
<a href="#leaderboard-blocked">Blocked</a> •
|
||||||
<a href="#leaderboard-owned-hats">Owned Hats</a> •
|
<a href="#leaderboard-owned-hats">Owned hats</a> •
|
||||||
<a href="#leaderboard-designed-hats">Designed Hats</a>
|
<a href="#leaderboard-designed-hats">Designed hats</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h5 class="font-weight-bolder text-center pt-2 pb-3"><a id="leaderboard-coins">Top 25 by coins</a></h5>
|
<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 %}
|
{% endif %}
|
||||||
</table>
|
</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>
|
<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">
|
<div class="overflow-x-auto"><table class="table table-striped mb-5">
|
||||||
|
@ -303,7 +268,7 @@
|
||||||
|
|
||||||
{% if users12 %}
|
{% 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">
|
<div class="overflow-x-auto"><table class="table table-striped mb-5">
|
||||||
<thead class="bg-primary text-white">
|
<thead class="bg-primary text-white">
|
||||||
|
@ -336,41 +301,7 @@
|
||||||
</table>
|
</table>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if users13 %}
|
<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-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>
|
|
||||||
|
|
||||||
<div class="overflow-x-auto"><table class="table table-striped mb-5">
|
<div class="overflow-x-auto"><table class="table table-striped mb-5">
|
||||||
<thead class="bg-primary text-white">
|
<thead class="bg-primary text-white">
|
||||||
|
@ -401,7 +332,7 @@
|
||||||
</table>
|
</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">
|
<div class="overflow-x-auto"><table class="table table-striped mb-5">
|
||||||
<thead class="bg-primary text-white">
|
<thead class="bg-primary text-white">
|
||||||
|
@ -431,7 +362,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</table>
|
</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">
|
<div class="overflow-x-auto"><table class="table table-striped mb-5">
|
||||||
<thead class="bg-primary text-white">
|
<thead class="bg-primary text-white">
|
||||||
|
|
|
@ -19,17 +19,6 @@
|
||||||
{{v.css | safe}}
|
{{v.css | safe}}
|
||||||
</style>
|
</style>
|
||||||
{% endif %}
|
{% 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 %}
|
{% else %}
|
||||||
<style>:root{--primary:#{{DEFAULT_COLOR}}</style>
|
<style>:root{--primary:#{{DEFAULT_COLOR}}</style>
|
||||||
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
||||||
|
@ -162,4 +151,4 @@
|
||||||
|
|
||||||
<script defer src="{{'js/clipboard.js' | asset}}"></script>
|
<script defer src="{{'js/clipboard.js' | asset}}"></script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -46,17 +46,6 @@
|
||||||
{{v.css | safe}}
|
{{v.css | safe}}
|
||||||
</style>
|
</style>
|
||||||
{% endif %}
|
{% 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>
|
</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 %}>
|
<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>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -23,9 +23,8 @@
|
||||||
<a class="btn btn-primary btn-block" href="/create_hole">CREATE {{HOLE_NAME|upper}}</a>
|
<a class="btn btn-primary btn-block" href="/create_hole">CREATE {{HOLE_NAME|upper}}</a>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
<a class="btn btn-primary btn-block" href="/holes">BROWSE {{HOLE_NAME|upper}}S</a>
|
<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="/">
|
<a class="btn btn-primary btn-block mt-5" href="/live">
|
||||||
<span style="display: block;font-size: 1.35rem;">STREAM LIST</span>
|
<span style="display: block; font-size: 1.5rem; line-height: 2;">LIVE LIST</span>
|
||||||
<span style="display: block;font-size: 0.85rem;">Coming Sometime 2022</span>
|
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-primary btn-block" href="/post/4103">BUGS/SUGGESTIONS MEGATHREAD</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>
|
<a class="btn btn-primary btn-block" href="/post/9694" >OFFICIAL CONSPIRACY THEORY THREAD</a>
|
||||||
|
|
|
@ -112,7 +112,7 @@
|
||||||
required="">
|
required="">
|
||||||
<div class="custom-control custom-checkbox mt-4">
|
<div class="custom-control custom-checkbox mt-4">
|
||||||
<input autocomplete="off" type="checkbox" class="custom-control-input" id="termsCheck" required>
|
<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>
|
</div>
|
||||||
|
|
||||||
{% if hcaptcha %}
|
{% if hcaptcha %}
|
||||||
|
|
|
@ -44,17 +44,6 @@
|
||||||
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
|
||||||
<link rel="stylesheet" href="{{('css/'~DEFAULT_THEME~'.css') | asset}}">
|
<link rel="stylesheet" href="{{('css/'~DEFAULT_THEME~'.css') | asset}}">
|
||||||
{% endif %}
|
{% 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 %}
|
{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -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)}}">
|
<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 %}
|
{%- endif %}
|
||||||
</div>
|
</div>
|
||||||
<span {% if user.patron %}class="patron" style="background-color:#{{user.name_color}}"{% endif %}>{{user.username}}</span>
|
<span {% if user.patron %}class="patron" style="background-color:#{{user.name_color}}"{% endif %}>{{user.user_name}}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
</h5>
|
</h5>
|
||||||
{% 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 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 %}
|
{% if u.username != u.original_username %}
|
||||||
<span id="profile--origname">
|
<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>
|
<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 %}
|
{% 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 %}
|
{% if u.username != u.original_username %}
|
||||||
<span id="profile-mobile--origname">
|
<span id="profile-mobile--origname">
|
||||||
|
|
|
@ -5,7 +5,7 @@ from files.__main__ import app
|
||||||
# these tests require `docker-compose up` first
|
# these tests require `docker-compose up` first
|
||||||
|
|
||||||
def test_rules():
|
def test_rules():
|
||||||
response = app.test_client().get("/logged_out/rules")
|
response = app.test_client().get("/sidebar")
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.text.startswith("<!DOCTYPE html>")
|
assert response.text.startswith("<!DOCTYPE html>")
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,10 @@ server {
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "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 {
|
location /chat {
|
||||||
proxy_pass http://127.0.0.1:5001/chat;
|
proxy_pass http://localhost:5001/chat;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /images/ {
|
location /images/ {
|
||||||
|
|
1372
redis.conf
40
schema.sql
|
@ -166,8 +166,7 @@ CREATE TABLE public.award_relationships (
|
||||||
comment_id integer,
|
comment_id integer,
|
||||||
kind character varying(20) NOT NULL,
|
kind character varying(20) NOT NULL,
|
||||||
awarded_utc integer,
|
awarded_utc integer,
|
||||||
created_utc integer,
|
created_utc integer
|
||||||
granted_by 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: -
|
-- Name: modactions; Type: TABLE; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
@ -1319,6 +1331,14 @@ ALTER TABLE ONLY public.marseys
|
||||||
ADD CONSTRAINT marseys_pkey PRIMARY KEY (name);
|
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: -
|
-- 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);
|
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: -
|
-- 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);
|
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: -
|
-- Name: mods mod_sub_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
|
|
@ -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 (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 (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);
|
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: -
|
-- 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),
|
('marseycapitalistmanlet',2,'money top hat rich landlord cigar llm tophat',NULL),
|
||||||
('marseycapy',2,'capybara rodent aevann happy cute',NULL),
|
('marseycapy',2,'capybara rodent aevann happy cute',NULL),
|
||||||
('marseycapy2022',2,'aevann caypbara new year party celebration',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),
|
('marseycapybigbrain',2,'capybara aevann smart codecel brain',NULL),
|
||||||
('marseycapyblackface',2,'racist minstrelsy bowtie racism capybara aevann',NULL),
|
('marseycapyblackface',2,'racist minstrelsy bowtie racism capybara aevann',NULL),
|
||||||
('marseycapyblowkiss',2,'capybara rodent aevann happy cute love',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),
|
('marseyvibing',2,'animated bopping vibe jam dancing headbang music rainbow dance',NULL),
|
||||||
('marseyvietnam',2,'army born to kill soldier war',NULL),
|
('marseyvietnam',2,'army born to kill soldier war',NULL),
|
||||||
('marseyvirus',2,'phage infect infection plagued',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),
|
('marseyw',2,'win winner dub',NULL),
|
||||||
('marseywagie',2,'crypto rightoid ancap poor wagecuck mcdonalds maccas reaction',NULL),
|
('marseywagie',2,'crypto rightoid ancap poor wagecuck mcdonalds maccas reaction',NULL),
|
||||||
('marseywait',2,'time watch wait waiting bored',NULL),
|
('marseywait',2,'time watch wait waiting bored',NULL),
|
||||||
|
|
|
@ -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;
|
|
|
@ -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);
|
|
@ -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 update
|
||||||
apt -y upgrade
|
apt -y upgrade
|
||||||
apt -y install git redis-server python3-pip ffmpeg imagemagick tmux nginx snapd ufw gpg-agent htop nano
|
apt -y install git redis-server python3-pip ffmpeg imagemagick tmux nginx snapd ufw gpg-agent htop nano
|
||||||
|
|