big chungus commit

remotes/1693045480750635534/spooky-22
Aevann1 2022-02-12 01:32:14 +02:00
parent 1ce8a577c6
commit 97febe0080
40 changed files with 355 additions and 127 deletions

View File

@ -6,44 +6,10 @@ services:
context: .
volumes:
- "./:/service"
env_file: env
environment:
- DATABASE_URL=postgresql://postgres@postgres:5432
- MASTER_KEY=3435tdfsdudebussylmaoxxt43
- REDIS_URL=redis://redis
- DOMAIN=localhost
- SITE_NAME=Drama
- GIPHY_KEY=3435tdfsdudebussylmaoxxt43
- DISCORD_SERVER_ID=3435tdfsdudebussylmaoxxt43
- DISCORD_CLIENT_ID=3435tdfsdudebussylmaoxxt43
- DISCORD_CLIENT_SECRET=3435tdfsdudebussylmaoxxt43
- DISCORD_BOT_TOKEN=3435tdfsdudebussylmaoxxt43
#- HCAPTCHA_SITEKEY=3435tdfsdudebussylmaoxxt43
- HCAPTCHA_SECRET=3435tdfsdudebussylmaoxxt43
- YOUTUBE_KEY=3435tdfsdudebussylmaoxxt43
#- PUSHER_ID=3435tdfsdudebussylmaoxxt43
- PUSHER_KEY=3435tdfsdudebussylmaoxxt43
- IMGUR_KEY=3435tdfsdudebussylmaoxxt43
- SPAM_SIMILARITY_THRESHOLD=0.5
- SPAM_URL_SIMILARITY_THRESHOLD=0.1
- SPAM_SIMILAR_COUNT_THRESHOLD=10
- COMMENT_SPAM_SIMILAR_THRESHOLD=0.5
- COMMENT_SPAM_COUNT_THRESHOLD=10
- READ_ONLY=0
- BOT_DISABLE=0
- DEFAULT_TIME_FILTER=all
- DEFAULT_THEME=midnight
- DEFAULT_COLOR=ff66ac
- GUMROAD_TOKEN=3435tdfsdudebussylmaoxxt43
- GUMROAD_LINK=https://marsey1.gumroad.com/l/tfcvri
- GUMROAD_ID=tfcvri
- CARD_VIEW=1
- DISABLE_DOWNVOTES=0
- DUES=0
- MAIL_USERNAME=blahblahblah@gmail.com
- MAIL_PASSWORD=3435tdfsdudebussylmaoxxt43
- DESCRIPTION=rdrama.net caters to drama in all forms such as Real life, videos, photos, gossip, rumors, news sites, Reddit, and Beyond™. There isn't drama we won't touch, and we want it all!
- CF_KEY=3435tdfsdudebussylmaoxxt43
- CF_ZONE=3435tdfsdudebussylmaoxxt43
links:
- "redis"
- "postgres"

View File

@ -1,4 +1,3 @@
export DATABASE_URL="postgresql://postgres@localhost:5432"
export MASTER_KEY="3435tdfsdudebussylmaoxxt43"
export DOMAIN="localhost"
export SITE_NAME="Drama"

View File

@ -30,7 +30,7 @@ faulthandler.enable()
app.config["SITE_NAME"]=environ.get("SITE_NAME").strip()
app.config["GUMROAD_LINK"]=environ.get("GUMROAD_LINK", "https://marsey1.gumroad.com/l/tfcvri").strip()
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['DATABASE_URL'] = environ.get("DATABASE_URL")
app.config['DATABASE_URL'] = environ.get("DATABASE_URL", "postgresql://postgres@localhost:5432")
app.config['SECRET_KEY'] = environ.get('MASTER_KEY')
app.config["SERVER_NAME"] = environ.get("DOMAIN").strip()
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 2628000

View File

@ -242,12 +242,7 @@ class Comment(Base):
@property
@lazy
def permalink(self):
if self.post and self.post.club:
if self.post.sub: f"{SITE_FULL}/s/{self.post.sub}/comment/{self.id}?context=8#context"
else: f"{SITE_FULL}/comment/{self.id}?context=8#context"
if self.post: return f"{self.post.permalink}/{self.id}?context=8#context"
else: return f"{SITE_FULL}/comment/{self.id}?context=8#context"
return f"{SITE_FULL}/comment/{self.id}?context=8#context"
@property
@lazy

View File

@ -1,12 +1,20 @@
from sqlalchemy import *
from sqlalchemy.orm import relationship
from files.__main__ import Base
from files.helpers.lazy import *
from time import strftime, gmtime
class Mod(Base):
__tablename__ = "mods"
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True)
sub = Column(String, ForeignKey("subs.name"), primary_key=True)
created_utc = Column(Integer)
def __repr__(self):
return f"<Mod(user_id={self.user_id}, sub={self.sub})>"
return f"<Mod(user_id={self.user_id}, sub={self.sub})>"
@property
@lazy
def created_datetime(self):
return str(strftime("%d/%B/%Y %H:%M:%S UTC", gmtime(self.created_utc)))

View File

@ -2,9 +2,11 @@ from sqlalchemy import *
from files.__main__ import Base
from files.helpers.lazy import lazy
from os import environ
from files.helpers.const import *
SITE_NAME = environ.get("SITE_NAME", '').strip()
SITE = environ.get("DOMAIN", '').strip()
if SITE == "localhost": SITE_FULL = 'http://' + SITE
else: SITE_FULL = 'https://' + SITE
class Sub(Base):
@ -14,6 +16,7 @@ class Sub(Base):
sidebar_html = Column(String)
sidebarurl = Column(String)
bannerurl = Column(String)
css = Column(String)
def __repr__(self):
return f"<Sub(name={self.name})>"

View File

@ -153,7 +153,14 @@ class User(Base):
@lazy
def mods(self, sub):
return self.admin_level > 1 or g.db.query(Mod.user_id).filter_by(user_id=self.id, sub=sub).one_or_none()
return self.id == AEVANN_ID or g.db.query(Mod.user_id).filter_by(user_id=self.id, sub=sub).one_or_none()
@lazy
def mod_date(self, sub):
if self.id == AEVANN_ID: return 1
mod = g.db.query(Mod).filter_by(user_id=self.id, sub=sub).one_or_none()
if not mod: return None
return mod.created_utc
@property
@lazy

View File

@ -362,6 +362,14 @@ AWARDS = {
"color": "text-pink",
"price": 300
},
"scooter": {
"kind": "scooter",
"title": "Scooter",
"description": "Summons a scooter on the post.",
"icon": "fas fa-flag-usa",
"color": "text-muted",
"price": 300
},
"wholesome": {
"kind": "wholesome",
"title": "Wholesome",
@ -369,6 +377,14 @@ AWARDS = {
"icon": "fas fa-smile-beam",
"color": "text-yellow",
"price": 300
},
"tilt": {
"kind": "tilt",
"title": "Tilt",
"description": "Tilts the post by 1 degree (up to 4)",
"icon": "fas fa-car-tilt",
"color": "text-blue",
"price": 300
},
"ghosts": {
"kind": "ghosts",

View File

@ -7,7 +7,11 @@ from os import path, environ
import re
from mistletoe import markdown
from json import loads, dump
from random import random
from random import random, choice
db = db_session()
marseys = tuple(x[0] for x in db.query(Marsey.name).all())
db.close()
allowed_tags = tags = ['b',
'blockquote',
@ -203,7 +207,9 @@ def sanitize(sanitized, noimages=False, alert=False, comment=False, edit=False):
classes = 'emoji-md'
remoji = emoji
if not edit and random() < 0.005 and 'marsey' in emoji: classes += ' golden'
if not edit and random() < 0.005 and ('marsey' in emoji or emoji in marseys): classes += ' golden'
if remoji == 'marseyrandom': remoji = choice(marseys)
if path.isfile(f'files/assets/images/emojis/{remoji}.webp'):
new = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}:" title=":{emoji}:" delay="0" class="{classes}" src="/static/assets/images/emojis/{remoji}.webp" >', new, re.I)
@ -218,14 +224,20 @@ def sanitize(sanitized, noimages=False, alert=False, comment=False, edit=False):
if emoji.startswith("!"):
emoji = emoji[1:]
classes = 'emoji mirrored'
if not edit and random() < 0.005 and 'marsey' in emoji: classes += ' golden'
if not edit and random() < 0.005 and ('marsey' in emoji or emoji in marseys): classes += ' golden'
if emoji == 'marseyrandom': emoji = random.choice(marseys)
if path.isfile(f'files/assets/images/emojis/{emoji}.webp'):
sanitized = re.sub(f'(?<!"):!{i.group(1).lower()[1:]}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":!{emoji}:" title=":!{emoji}:" delay="0" class="{classes}" src="/static/assets/images/emojis/{emoji}.webp">', sanitized, re.I)
if comment: marseys_used.add(emoji)
elif path.isfile(f'files/assets/images/emojis/{emoji}.webp'):
classes = 'emoji'
if not edit and random() < 0.005 and 'marsey' in emoji: classes += ' golden'
if not edit and random() < 0.005 and ('marsey' in emoji or emoji in marseys): classes += ' golden'
if emoji == 'marseyrandom': emoji = random.choice(marseys)
sanitized = re.sub(f'(?<!"):{i.group(1).lower()}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}:" title=":{emoji}:" delay="0" class="{classes}" src="/static/assets/images/emojis/{emoji}.webp">', sanitized, re.I)
if comment: marseys_used.add(emoji)
@ -284,13 +296,19 @@ def filter_emojis_only(title, edit=False):
if emoji.startswith("!"):
emoji = emoji[1:]
classes = 'emoji mirrored'
if not edit and random() < 0.005 and 'marsey' in emoji: classes += ' golden'
if not edit and random() < 0.005 and ('marsey' in emoji or emoji in marseys): classes += ' golden'
if emoji == 'marseyrandom': emoji = random.choice(marseys)
if path.isfile(f'files/assets/images/emojis/{emoji}.webp'):
title = re.sub(f'(?<!"):!{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":!{emoji}:" title=":!{emoji}:" delay="0" src="/static/assets/images/emojis/{emoji}.webp" class="{classes}">', title, re.I)
elif path.isfile(f'files/assets/images/emojis/{emoji}.webp'):
classes = 'emoji'
if not edit and random() < 0.005 and 'marsey' in emoji: classes += ' golden'
if not edit and random() < 0.005 and ('marsey' in emoji or emoji in marseys): classes += ' golden'
if emoji == 'marseyrandom': emoji = random.choice(marseys)
title = re.sub(f'(?<!"):{emoji}:', f'<img loading="lazy" data-bs-toggle="tooltip" alt=":{emoji}:" title=":{emoji}:" delay="0" class="{classes}" src="/static/assets/images/emojis/{emoji}.webp">', title, re.I)
if len(title) > 1500: abort(400)

View File

@ -42,6 +42,14 @@ AWARDS3 = {
"color": "text-pink",
"price": 300
},
"scooter": {
"kind": "scooter",
"title": "Scooter",
"description": "Summons a scooter on the post.",
"icon": "fas fa-flag-usa",
"color": "text-muted",
"price": 300
},
"wholesome": {
"kind": "wholesome",
"title": "Wholesome",
@ -50,6 +58,14 @@ AWARDS3 = {
"color": "text-yellow",
"price": 300
},
"tilt": {
"kind": "tilt",
"title": "Tilt",
"description": "Tilts the post by 1 degree (up to 4)",
"icon": "fas fa-car-tilt",
"color": "text-blue",
"price": 300
},
}
@app.get("/shop")

View File

@ -956,6 +956,49 @@ def unpin_comment(cid, v):
g.db.commit()
return {"message": "Comment unpinned!"}
@app.post("/mod_pin/<cid>")
@auth_required
def mod_pin(cid, v):
comment = get_comment(cid, v=v)
if not comment: abort(404)
if not (comment.post.sub and v.mods(comment.post.sub)): abort(403)
comment.is_pinned = v.username + " (Mod)"
g.db.add(comment)
if v.id != comment.author_id:
message = f"@{v.username} (Mod) has pinned your [comment]({comment.permalink})!"
send_repeatable_notification(comment.author_id, message)
g.db.commit()
return {"message": "Comment pinned!"}
@app.post("/mod_unpin/<cid>")
@auth_required
def mod_unpin(cid, v):
comment = get_comment(cid, v=v)
if not comment: abort(404)
if not (comment.post.sub and v.mods(comment.post.sub)): abort(403)
comment.is_pinned = None
g.db.add(comment)
if v.id != comment.author_id:
message = f"@{v.username} (Mod) has unpinned your [comment]({comment.permalink})!"
send_repeatable_notification(comment.author_id, message)
g.db.commit()
return {"message": "Comment unpinned!"}
@app.post("/save_comment/<cid>")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@auth_required

View File

@ -9,18 +9,18 @@ valid_sub_regex = re.compile("^[a-zA-Z0-9_\-]{3,25}$")
@app.get("/s/<sub>/mods")
@is_not_permabanned
def mods(v, sub):
sub = g.db.query(Sub).filter_by(name=sub.lower()).one_or_none()
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
if not sub: abort(404)
mods = [x[0] for x in g.db.query(Mod.user_id).filter_by(sub=sub.name).all()]
users = g.db.query(User).filter(User.id.in_(mods)).all()
users = g.db.query(User, Mod).join(Mod, Mod.user_id==User.id).filter_by(sub=sub.name).order_by(Mod.created_utc).all()
return render_template("sub/mods.html", v=v, sub=sub, users=users)
@app.post("/s/<sub>/add_mod")
@is_not_permabanned
def add_mod(v, sub):
sub = g.db.query(Sub).filter_by(name=sub.lower()).one_or_none()
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
if not sub: abort(404)
sub = sub.name
@ -32,10 +32,41 @@ def add_mod(v, sub):
user = get_user(user)
mod = Mod(user_id=user.id, sub=sub)
g.db.add(mod)
existing = g.db.query(Mod).filter_by(user_id=user.id, sub=sub).one_or_none()
send_repeatable_notification(user.id, f"You have been added as a mod to /s/{sub}")
if not existing:
mod = Mod(user_id=user.id, sub=sub, created_utc=int(time.time()))
g.db.add(mod)
send_repeatable_notification(user.id, f"You have been added as a mod to /s/{sub}")
g.db.commit()
return redirect(f'/s/{sub}/mods')
@app.post("/s/<sub>/remove_mod")
@is_not_permabanned
def remove_mod(v, sub):
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
if not sub: abort(404)
sub = sub.name
if not v.mods(sub): abort(403)
uid = request.values.get('uid')
if not uid: abort(400)
try: uid = int(uid)
except: abort(400)
mod = g.db.query(Mod).filter_by(user_id=uid, sub=sub).one_or_none()
if not mod: abort(400)
g.db.delete(mod)
send_repeatable_notification(uid, f"You have been removed as a mod from /s/{sub}")
g.db.commit()
@ -70,7 +101,7 @@ def create_sub2(v):
sub = Sub(name=name)
g.db.add(sub)
mod = Mod(user_id=v.id, sub=sub.name)
mod = Mod(user_id=v.id, sub=sub.name, created_utc=int(time.time()))
g.db.add(mod)
g.db.commit()
@ -111,26 +142,47 @@ def sub_settings(v, sub):
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@is_not_permabanned
def post_sub_sidebar(v, sub):
sub = g.db.query(Sub).filter_by(name=sub.lower()).one_or_none()
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
if not sub: abort(404)
if not v.mods(sub.name): abort(403)
sub.sidebar = request.values.get('sidebar', '').strip()
sub.sidebar = request.values.get('sidebar', '').strip()[:500]
sub.sidebar_html = sanitize(sub.sidebar)
g.db.add(sub)
if len(sub.sidebar_html) > 1000: return "Sidebar is too big!"
ma = ModAction(
kind="change_sidebar",
user_id=v.id
)
g.db.add(ma)
g.db.add(sub)
g.db.commit()
return redirect(f'/s/{sub.name}/settings')
@app.post('/s/<sub>/css')
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@is_not_permabanned
def post_sub_css(v, sub):
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
if not sub: abort(404)
if not v.mods(sub.name): abort(403)
sub.css = request.values.get('css', '').strip()
g.db.add(sub)
g.db.commit()
return redirect(f'/s/{sub.name}/settings')
@app.get("/s/<sub>/css")
def get_sub_css(sub):
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
if not sub: abort(404)
resp=make_response(sub.css or "")
resp.headers.add("Content-Type", "text/css")
return resp
@app.post("/s/<sub>/banner")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@is_not_permabanned

View File

@ -392,9 +392,7 @@ def leaderboard(v):
@app.get("/@<username>/css")
def get_css(username):
user = get_user(username)
if user.css: css = user.css
else: css = ""
resp=make_response(css)
resp=make_response(user.css or "")
resp.headers.add("Content-Type", "text/css")
return resp

View File

@ -25,7 +25,7 @@
</div>
<div class="body d-lg-flex">
<div class="w-lg-100">
<form id="profile-settings" action="{% if sub %}/s/{{sub.name}}{% else %}/admin{% endif %}/sidebar" method="post">
<form id="profile-settings" action="/admin/sidebar" method="post">
<input autocomplete="off" type="hidden" name="formkey" value="{{v.formkey}}">
<textarea autocomplete="off" maxlength="10000" class="form-control rounded" id="bio-text" aria-label="With textarea" placeholder="Enter sidebar here..." rows="50" name="sidebar" form="profile-settings">{% if sidebar %}{{sidebar}}{% endif %}</textarea>

View File

@ -15,7 +15,7 @@
{% if v %}
<style>:root{--primary:#{{v.themecolor}}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120"><link rel="stylesheet" href="/static/assets/css/{{v.theme}}.css?a=21">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122"><link rel="stylesheet" href="/static/assets/css/{{v.theme}}.css?a=21">
{% if v.agendaposter %}
<style>
html {

View File

@ -488,14 +488,14 @@
{% endif %}
{% if v and c.post %}
{% if v.admin_level > 1 %}
{% if v.admin_level > 1%}
<button id="unpin-{{c.id}}" class="btn caction py-0 nobackground {% if c.is_pinned %}d-md-inline-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/unsticky_comment/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Unpin</button>
<button id="pin-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if not c.is_pinned %}d-md-inline-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/sticky_comment/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Pin</button>
{% elif v.id == c.post.author_id %}
<button id="unpin-{{c.id}}" class="btn caction py-0 nobackground {% if c.is_pinned %}d-md-inline-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/unpin_comment/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Unpin</button>
{% elif v.id == c.post.author_id or c.post.sub and v.mods(c.post.sub) %}
<button id="unpin-{{c.id}}" class="btn caction py-0 nobackground {% if c.is_pinned %}d-md-inline-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/mod_unpin/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Unpin</button>
<button id="pin-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if not c.is_pinned %}d-md-inline-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/pin_comment/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Pin</button>
<button id="pin-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if not c.is_pinned %}d-md-inline-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast3('/mod_pin/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Pin</button>
{% endif %}
{% endif %}
@ -626,7 +626,7 @@
<a role="button" role="button" class="list-group-item copy-link" data-bs-dismiss="modal" data-clipboard-text="{% if SITE_NAME == 'Drama' %}https://rdrama.com{{c.shortlink_context}}{% else %}{{c.permalink}}{% endif %}"><i class="fas fa-copy"></i>Copy link</a>
<a class="list-group-item" href="{{c.permalink}}"><i class="fas fa-dna"></i>Context</a>
<a class="list-group-item" href="{{c.permalink}}"><i class="fas fa-book-open"></i>Context</a>
{% if v %}
<a role="button" data-bs-toggle="modal" data-bs-dismiss="modal" data-bs-target="#reportCommentModal" onclick="report_commentModal('{{c.id}}','{{c.author_name}}')" class="list-group-item"><i class="fas fa-flag"></i>Report</a>
@ -667,9 +667,9 @@
{% endif %}
{% if c.post and v.id == c.post.author_id and v.admin_level < 2 %}
<a id="pin2-{{c.id}}" class="list-group-item {% if c.is_pinned %}d-none{% endif %} text-info" role="button" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast2('/pin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Pin</a>
<a id="unpin2-{{c.id}}" class="list-group-item {% if not c.is_pinned %}d-none{% endif %} text-info" role="button" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast2('/unpin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Unpin</a>
{% if c.post and v.id == c.post.author_id and v.admin_level < 2 or c.post.sub and v.mods(c.post.sub) %}
<a id="pin2-{{c.id}}" class="list-group-item {% if c.is_pinned %}d-none{% endif %} text-info" role="button" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast2('/mod_pin/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Pin</a>
<a id="unpin2-{{c.id}}" class="list-group-item {% if not c.is_pinned %}d-none{% endif %} text-info" role="button" data-bs-target="#actionsModal-{{c.id}}" onclick="post_toast2('/mod_unpin/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info"></i>Unpin</a>
{% endif %}
{% endif %}
</ul>
@ -911,7 +911,7 @@
</style>
{% if v %}
<script src="/static/assets/js/marked.js?a=241"></script>
<script src="/static/assets/js/marked.js?a=242"></script>
<script src="/static/assets/js/comments_v.js?a=243"></script>
{% endif %}

View File

@ -7,7 +7,7 @@
<script src="/static/assets/js/bootstrap.js?a=240"></script>
{% if v %}
<style>:root{--primary:#{{v.themecolor}}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122">
<link rel="stylesheet" href="/static/assets/css/{{v.theme}}.css?a=21">
{% if v.agendaposter %}
<style>
@ -32,9 +32,13 @@
{% endif %}
{% else %}
<style>:root{--primary:#{{config('DEFAULT_COLOR')}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120"><link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122"><link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
{% endif %}
{% if sub and sub.css and not request.path.endswith('settings') %}
<link rel="stylesheet" href="/s/{{sub.name}}/css" type="text/css">
{% endif %}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
@ -217,9 +221,7 @@
{% if v %}
{% if sub %}
<a href="{{sub.banner_url}}">
<img alt="/s/{[sub.name]} banner" src="{{sub.banner_url}}" width=100% style="object-fit:cover;max-height:35vh">
</a>
<img alt="/s/{{sub.name}} banner" role="button" data-bs-toggle="modal" data-bs-target="#expandImageModal" onclick="expandDesktopImage('{{sub.banner_url}}')" loading="lazy" src="{{sub.banner_url}}" width=100% style="object-fit:cover;max-height:35vh">
{% elif SITE_NAME == 'Drama' %}
{% set path = "assets/images/" + SITE_NAME + "/banners_bhm" %}
{% set image = "/static/" + path + "/" + listdir('files/' + path)|random() + '?a=21' %}

View File

@ -18,6 +18,9 @@
<li class="nav-item">
<a class="nav-link emojitab" data-bs-toggle="tab" href="#emoji-tab-marsey">Marsey</a>
</li>
<li class="nav-item">
<a class="nav-link emojitab" data-bs-toggle="tab" href="#emoji-tab-marseyalphabet">Marsey Alphabet</a>
</li>
<li class="nav-item">
<a class="nav-link emojitab" data-bs-toggle="tab" href="#emoji-tab-platy">Platy</a>
</li>
@ -69,6 +72,9 @@
<div class="tab-pane fade" id="emoji-tab-marsey">
<div class="d-flex flex-wrap py-3 pl-2" id="EMOJIS_marsey"></div>
</div>
<div class="tab-pane fade" id="emoji-tab-marseyalphabet">
<div class="d-flex flex-wrap py-3 pl-2" id="EMOJIS_marseyalphabet"></div>
</div>
<div class="tab-pane fade" id="emoji-tab-platy">
<div class="d-flex flex-wrap py-3 pl-2" id="EMOJIS_platy"></div>
</div>
@ -100,7 +106,7 @@
</div>
</div>
<script data-cfasync="false" src="/static/assets/js/emoji_modal.js?a=243"></script>
<script data-cfasync="false" src="/static/assets/js/emoji_modal.js?a=244"></script>
<style>
a.emojitab {

View File

@ -14,7 +14,7 @@
<pre></pre>
<h1 class="h5">500 Internal Server Error</h1>
<p class="text-muted mb-5">Hiiiii it's carp! I think this error means that there's a timeout error. And I think that means something took too long to load so it decided not to work at all. If you keep seeing this on the same page <I>but not other pages</I>, then something is probably wrong with that specific function. It may not be called a function, but that sounds right to me. Anyway, ping me and I'll whine to someone smarter to fix it. Don't bother them. Thanks ily <3</p>
<div><a href="/" class="btn btn-primary">Go to main feed</a></div>
<div><a href="/" class="btn btn-primary">Go to the frontpage</a></div>
</div>
</div>

View File

@ -86,6 +86,11 @@ You can use Markdown formatting:
<td>:#!marseylove:</td>
<td><img loading="lazy" data-bs-toggle="tooltip" class="emoji-lg mirrored" alt=":!marseylove:" data-bs-original-title=":!marseylove:" delay="0" src="/static/assets/images/emojis/marseylove.webp?a=1008"></td>
</tr>
<tr>
<td>Random Marsey</td>
<td>:marseyrandom:</td>
<td>???</td>
</tr>
<tr>
<td>Poll Options (can select multiple options)</td>
<td>$$bussy$$ $$gussy$$</td>

View File

@ -147,7 +147,7 @@
<button class="dropdown-item copy-link" data-clipboard-text="{{SITE_FULL}}/signup?ref={{v.username}}"><i class="fad fa-user-friends fa-fw text-left mr-3"></i>Invite friends</button>
</div>
<div class="px-2">
<a class="dropdown-item" href="/assets/{{config('SITE_NAME')}}_v1.7.apk?a=1"><i class="fab fa-android fa-fw text-left mr-3"></i>Android app</a>
<a class="dropdown-item" href="/assets/{{config('SITE_NAME')}}_v1.7.apk?a=2"><i class="fab fa-android fa-fw text-left mr-3"></i>Android app</a>
<a class="dropdown-item" href="/changelog"><i class="fas fa-clipboard fa-fw text-left mr-3"></i>Changelog</a>
@ -208,7 +208,7 @@
<a class="nav-link copy-link" data-clipboard-text="{{SITE_FULL}}/signup?ref={{v.username}}"><i class="fas fa-user-friends fa-fw text-left mr-3"></i>Invite friends</a>
</li>
{% endif %}
<a class="nav-item nav-link" href="/assets/{{config('SITE_NAME')}}_v1.7.apk?a=1"><i class="fab fa-android fa-fw mr-3"></i>Android app</a>
<a class="nav-item nav-link" href="/assets/{{config('SITE_NAME')}}_v1.7.apk?a=2"><i class="fab fa-android fa-fw mr-3"></i>Android app</a>
<a class="nav-item nav-link" rel="nofollow noopener noreferrer" href="https://github.com/Aevann1/Drama"><i class="fab fa-github fa-fw mr-3"></i>Source code</a>

View File

@ -6,7 +6,7 @@
{% block content %}
{% if v %}
<style>:root{--primary:#{{v.themecolor}}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120"><link rel="stylesheet" href="/static/assets/css/{{v.theme}}.css?a=21">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122"><link rel="stylesheet" href="/static/assets/css/{{v.theme}}.css?a=21">
{% if v.agendaposter %}
<style>
html {
@ -30,7 +30,7 @@
{% endif %}
{% else %}
<style>:root{--primary:#{{config('DEFAULT_COLOR')}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120"><link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122"><link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
{% endif %}
<div class="row justify-content-around">

View File

@ -18,7 +18,7 @@
{% endblock %}
<style>:root{--primary:#{{config('DEFAULT_COLOR')}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122">
<link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
</head>

View File

@ -14,7 +14,7 @@
<title>2-Step Login - {{SITE_NAME}}</title>
<style>:root{--primary:#{{config('DEFAULT_COLOR')}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120"><link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122"><link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
</head>

View File

@ -30,7 +30,7 @@
Messages
</a>
</li>
{% if v.admin_level > 2 %}
{% if v.admin_level > 1 %}
<li class="nav-item">
<a class="nav-link py-3{% if '/notifications?modmail=true' in request.full_path %} active{% endif %}" href="/notifications?modmail=true">
Modmail

View File

@ -34,7 +34,7 @@
<style>:root{--primary:#{{v.themecolor}}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120"><link rel="stylesheet" href="/static/assets/css/{{v.theme}}.css?a=21">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122"><link rel="stylesheet" href="/static/assets/css/{{v.theme}}.css?a=21">
{% if v.agendaposter %}
<style>
html {

View File

@ -39,10 +39,10 @@
{% if v %}
<style>:root{--primary:#{{v.themecolor}}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120"><link rel="stylesheet" href="/static/assets/css/{{v.theme}}.css?a=21">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122"><link rel="stylesheet" href="/static/assets/css/{{v.theme}}.css?a=21">
{% else %}
<style>:root{--primary:#{{config('DEFAULT_COLOR')}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120"><link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122"><link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
{% endif %}
</head>

View File

@ -5,7 +5,7 @@
{% set image='/static/assets/images/2Much4You/sidebar.webp?a=1039' %}
{% endif %}
<img role="button" data-bs-toggle="modal" data-bs-target="#expandImageModal" onclick="expandDesktopImage('{{image}}')" loading="lazy" src="{{image}}" width=100%>
<img alt="sidebar image" role="button" data-bs-toggle="modal" data-bs-target="#expandImageModal" onclick="expandDesktopImage('{{image}}')" loading="lazy" src="{{image}}" width=100%>
{% if sub %}

View File

@ -1,5 +1,5 @@
<div class="col sidebar text-left d-none d-lg-block pt-3 bg-white" style="max-width:300px">
<img role="button" data-bs-toggle="modal" data-bs-target="#expandImageModal" onclick="expandDesktopImage('/static/assets/images/PCM/sidebar.webp?a=1008" loading="lazy" src="/static/assets/images/PCM/sidebar.webp?a=1008" width=100%>
<img alt="sidebar image" role="button" data-bs-toggle="modal" data-bs-target="#expandImageModal" onclick="expandDesktopImage('/static/assets/images/PCM/sidebar.webp?a=1008" loading="lazy" src="/static/assets/images/PCM/sidebar.webp?a=1008" width=100%>
<a class="btn btn-primary btn-block mt-4" href="https://ip2.network">STREAM LIST</a>

View File

@ -5,7 +5,7 @@
{% set image='/static/assets/images/ruqqus/sidebar.webp?a=1039' %}
{% endif %}
<img role="button" data-bs-toggle="modal" data-bs-target="#expandImageModal" onclick="expandDesktopImage('{{image}}')" loading="lazy" src="{{image}}" width=100%>
<img alt="sidebar image" role="button" data-bs-toggle="modal" data-bs-target="#expandImageModal" onclick="expandDesktopImage('{{image}}')" loading="lazy" src="{{image}}" width=100%>
{% if sub %}
{% if sub.sidebar_html %}

View File

@ -31,7 +31,7 @@
<title>{% if ref_user %}{{ref_user.username}} invites you to {{SITE_NAME}}{% else %}Sign up - {{SITE_NAME}}{% endif %}</title>
<style>:root{--primary:#{{config('DEFAULT_COLOR')}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120"><link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122"><link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
</head>

View File

@ -32,7 +32,7 @@
<title>{% if ref_user %}{{ref_user.username}} invites you to {{SITE_NAME}}{% else %}{{SITE_NAME}}{% endif %}</title>
<style>:root{--primary:#{{config('DEFAULT_COLOR')}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120"><link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122"><link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
</head>

View File

@ -11,12 +11,24 @@
<tr>
<th style="font-weight: bold">#</th>
<th style="font-weight: bold">Name</th>
<th style="font-weight: bold">Mod since</th>
<th style="font-weight: bold"></th>
</tr>
</thead>
{% for user in users %}
{% for user, mod in users %}
<tr>
<td style="font-weight: bold">{{loop.index}}</td>
<td><a style="color:#{{user.namecolor}}; font-weight:bold;" href="/@{{user.username}}"><img alt="@{{user.username}}'s profile picture" loading="lazy" src="{{user.profile_url}}" class="pp20"><span {% if user.patron %}class="patron" style="background-color:#{{user.namecolor}}"{% endif %}>{{user.username}}</span></a></td>
<td style="font-weight: bold">{{mod.created_datetime}}</td>
<td>
{% if v.mod_date(sub.name) and v.mod_date(sub.name) < mod.created_utc %}
<form action="/s/{{sub.name}}/remove_mod" method="post">
<input autocomplete="off" type="hidden" name="formkey" value="{{v.formkey}}" >
<input autocomplete="off" type="hidden" name="uid" value="{{user.id}}">
<input class="btn btn-primary" style="margin-top:-5px" autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Remove Mod">
</form>
{% endif %}
</td>
</tr>
{% endfor %}

View File

@ -16,7 +16,6 @@
</div>
{% endif %}
<h2 class="h5 mt-5">Sidebar Picture</h2>
<div class="settings-section rounded">
@ -50,6 +49,9 @@
</div>
</div>
<h2 class="h5 mt-5">Banner</h2>
<div class="settings-section rounded">
@ -84,6 +86,8 @@
</div>
<div class="row my-5 py-5">
<div class="col col-md-8">
<div class="settings">
@ -93,9 +97,34 @@
</div>
<div class="body d-lg-flex">
<div class="w-lg-100">
<form id="profile-settings" action="{% if sub %}/s/{{sub.name}}{% else %}/admin{% endif %}/sidebar" method="post">
<form id="sidebar" action="/s/{{sub.name}}/sidebar" method="post">
<input autocomplete="off" type="hidden" name="formkey" value="{{v.formkey}}">
<textarea autocomplete="off" maxlength="10000" class="form-control rounded" id="bio-text" aria-label="With textarea" placeholder="Enter sidebar here..." rows="50" name="sidebar" form="profile-settings">{% if sub.sidebar %}{{sub.sidebar}}{% endif %}</textarea>
<textarea autocomplete="off" maxlength="500" class="form-control rounded" id="bio-text" aria-label="With textarea" placeholder="Enter sidebar here..." rows="50" name="sidebar" form="sidebar">{% if sub.sidebar %}{{sub.sidebar}}{% endif %}</textarea>
<div class="d-flex mt-2">
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Save">
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div class="row my-5 py-5">
<div class="col col-md-8">
<div class="settings">
<div id="description">
<h2>Edit CSS</h2>
<br>
</div>
<div class="body d-lg-flex">
<div class="w-lg-100">
<form id="css" action="/s/{{sub.name}}/css" method="post">
<input autocomplete="off" type="hidden" name="formkey" value="{{v.formkey}}">
<textarea autocomplete="off" maxlength="4000" class="form-control rounded" id="bio-text" aria-label="With textarea" placeholder="Enter css here..." rows="50" name="css" form="css">{% if sub.css %}{{sub.css}}{% endif %}</textarea>
<div class="d-flex mt-2">
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Save">

View File

@ -153,23 +153,13 @@
{% endif %}
{% endif %}
{% if p.award_count("train") %}
{% if p.award_count("train") or p.award_count("scooter") %}
<style>
.train {
position:fixed;
z-index:9999;
pointer-events: none;
}
.trainimg {
width: 100px;
height: 51px;
}
@media (max-width: 992px) {
.trainimg {
width: 40px;
height: 20px;
}
}
.train1 {
top: 10%
}
@ -183,6 +173,21 @@
top: 85%
}
</style>
{% endif %}
{% if p.award_count("train") %}
<style>
.trainimg {
width: 100px;
height: 51px;
}
@media (max-width: 992px) {
.trainimg {
width: 40px;
height: 20px;
}
}
</style>
<marquee class="train train1" direction="left" scrollamount=10 width="100%">
<img alt=":#marseytrain:" class="trainimg mirrored" src="/static/assets/images/emojis/marseytrain.webp?a=1008">
@ -208,6 +213,54 @@
{% endif %}
{% if p.award_count("scooter") %}
<style>
.scooterimg {
width: 100px;
height: 135px;
}
@media (max-width: 992px) {
.scooterimg {
width: 40px;
height: 54px;
}
}
</style>
<marquee class="train train1" direction="left" scrollamount=10 width="100%">
<img alt=":#marseyscooter:" class="scooterimg mirrored" src="/static/assets/images/emojis/marseyscooter.webp?a=1008">
</marquee>
{% endif %}
{% if p.award_count("scooter") > 1 %}
<marquee class="train train2" direction="right" scrollamount=10 width="100%">
<img alt=":#marseyscooter:" class="scooterimg" src="/static/assets/images/emojis/marseyscooter.webp?a=1008">
</marquee>
{% endif %}
{% if p.award_count("scooter") > 2 %}
<marquee class="train train3" direction="left" scrollamount=10 width="100%">
<img alt=":#marseyscooter:" class="scooterimg mirrored" src="/static/assets/images/emojis/marseyscooter.webp?a=1008">
</marquee>
{% endif %}
{% if p.award_count("scooter") > 3 %}
<marquee class="train train4" direction="right" scrollamount=10 width="100%">
<img alt=":#marseyscooter:" class="scooterimg" src="/static/assets/images/emojis/marseyscooter.webp?a=1008">
</marquee>
{% endif %}
{% if p.award_count("tilt") %}
<style>
body {
transform: rotate({{(p.award_count("tilt"),4)|min}}deg);
}
</style>
{% endif %}
<meta charset="utf-8" >
<meta property="og:type" content="article" >

View File

@ -129,7 +129,7 @@
<img alt="post thumnail" loading="lazy" src="{{p.thumb_url}}" class="post-img">
</a>
{% elif p.is_image %}
<img role="button" data-bs-toggle="modal" data-bs-target="#expandImageModal" onclick="expandDesktopImage('{{p.realurl(v)}}')" alt="post thumnail" loading="lazy" src="{{p.thumb_url}}" class="post-img">
<img alt="sidebar image" role="button" data-bs-toggle="modal" data-bs-target="#expandImageModal" onclick="expandDesktopImage('{{p.realurl(v)}}')" alt="post thumnail" loading="lazy" src="{{p.thumb_url}}" class="post-img">
{% elif p.is_video %}
<a role="button" onclick="togglevideo({{p.id}})">
<img alt="post thumnail" loading="lazy" src="{{p.thumb_url}}" class="post-img">

View File

@ -26,7 +26,7 @@
{% block stylesheets %}
{% if v %}
<style>:root{--primary:#{{v.themecolor}}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120"><link rel="stylesheet" href="/static/assets/css/{{v.theme}}.css?a=21">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122"><link rel="stylesheet" href="/static/assets/css/{{v.theme}}.css?a=21">
{% if v.agendaposter %}
<style>
html {
@ -50,7 +50,7 @@
{% endif %}
{% else %}
<style>:root{--primary:#{{config('DEFAULT_COLOR')}}</style>
<link rel="stylesheet" href="/static/assets/css/main.css?a=120">
<link rel="stylesheet" href="/static/assets/css/main.css?a=122">
<link rel="stylesheet" href="/static/assets/css/{{config('DEFAULT_THEME')}}.css?a=21">
{% endif %}
{% endblock %}
@ -257,7 +257,7 @@
checkForRequired()
</script>
<script src="/static/assets/js/marked.js?a=241"></script>
<script src="/static/assets/js/marked.js?a=242"></script>
<script src="/static/assets/js/formatting.js?a=240"></script>
<script src="/static/assets/js/submit.js?a=243"></script>
{% include "emoji_modal.html" %}

View File

@ -704,7 +704,7 @@
{% if v %}
<div id='tax' class="d-none">{% if v.patron or u.patron or v.alts_patron or u.alts_patron %}0{% else %}0.03{% endif %}</div>
<script src="/static/assets/js/userpage_v.js?a=240"></script>
<script src="/static/assets/js/userpage_v.js?a=241"></script>
<div id="username" class="d-none">{{u.username}}</div>
{% endif %}
@ -734,7 +734,7 @@
</nav>
{% endif %}
<script src="/static/assets/js/marked.js?a=241"></script>
<script src="/static/assets/js/marked.js?a=242"></script>
<style>
.userbanner {

View File

@ -114,7 +114,7 @@
{% if v %}
<div id='tax' class="d-none">{% if v.patron or u.patron %}0{% else %}0.03{% endif %}</div>
<script src="/static/assets/js/userpage_v.js?a=240"></script>
<script src="/static/assets/js/userpage_v.js?a=241"></script>
<div id="username" class="d-none">{{u.username}}</div>
{% endif %}

View File

@ -48,7 +48,7 @@
{% if v %}
<div id='tax' class="d-none">{% if v.patron or u.patron %}0{% else %}0.03{% endif %}</div>
<script src="/static/assets/js/userpage_v.js?a=240"></script>
<script src="/static/assets/js/userpage_v.js?a=241"></script>
<div id="username" class="d-none">{{u.username}}</div>
{% endif %}