dude subdramas lmao

remotes/1693045480750635534/spooky-22
Aevann1 2022-02-10 22:35:16 +02:00
parent 03e99b2872
commit 03f1a106b4
29 changed files with 564 additions and 92 deletions

View File

@ -11,7 +11,7 @@ services:
- MASTER_KEY=3435tdfsdudebussylmaoxxt43
- REDIS_URL=redis://redis
- DOMAIN=localhost
- SITE_NAME=2Much4You
- SITE_NAME=Drama
- GIPHY_KEY=3435tdfsdudebussylmaoxxt43
- DISCORD_SERVER_ID=3435tdfsdudebussylmaoxxt43
- DISCORD_CLIENT_ID=3435tdfsdudebussylmaoxxt43

View File

@ -422,6 +422,10 @@ class Comment(Base):
return body
def print(self):
print(f'post: {self.id}, comment: {self.author_id}', flush=True)
return ''
@lazy
def collapse_for_user(self, v, path):
if v and self.author_id == v.id: return False

View File

@ -1,6 +1,5 @@
from sqlalchemy import *
from files.__main__ import Base
from files.helpers.lazy import lazy
class Marsey(Base):
__tablename__ = "marseys"

View File

@ -1,6 +1,9 @@
from sqlalchemy import *
from sqlalchemy.orm import relationship
from files.__main__ import Base
from files.helpers.lazy import lazy
from os import environ
SITE_NAME = environ.get("SITE_NAME", '').strip()
class Sub(Base):
@ -8,6 +11,20 @@ class Sub(Base):
name = Column(String, primary_key=True)
sidebar = Column(String)
sidebar_html = Column(String)
sidebarurl = Column(String)
bannerurl = Column(String)
def __repr__(self):
return f"<Sub(name={self.name})>"
return f"<Sub(name={self.name})>"
@property
@lazy
def sidebar_url(self):
if self.sidebarurl: return self.sidebarurl
return f'/static/assets/images/{SITE_NAME}/sidebar.webp?a=1039'
@property
@lazy
def banner_url(self):
if self.bannerurl: return self.bannerurl
return f'/static/assets/images/{SITE_NAME}/banner.webp?a=1039'

View File

@ -440,6 +440,10 @@ class Submission(Base):
return body
def print(self):
print(f'post: {self.id}, author: {self.author_id}', flush=True)
return ''
@lazy
def realtitle(self, v):
if self.club and not (v and (v.paid_dues or v.id == self.author_id)):

View File

@ -127,7 +127,8 @@ class User(Base):
original_username = deferred(Column(String))
referred_by = Column(Integer, ForeignKey("users.id"))
nwordpass = Column(Boolean)
subs_created = Column(Integer, default=0)
badges = relationship("Badge", viewonly=True)
subscriptions = relationship("Subscription", viewonly=True)
following = relationship("Follow", primaryjoin="Follow.user_id==User.id", viewonly=True)

View File

@ -142,7 +142,7 @@ AGENDAPOSTER_MSG = """Hi @{username},\n\nYour {type} has been automatically remo
included. \n\n*This is an automated message; if you need help,
you can message us [here](/contact).*"""
if SITE_NAME in ('Drama','2Much4You'):
if SITE in ('rdrama.net','devrama.xyz','2much4you.net','ruqqus.ga'):
PW_ID = 3750
BASEDBOT_ID = 0
KIPPY_ID = 7150
@ -575,10 +575,6 @@ FORTUNE_REPLIES = ('<b style="color:#6023f8">Your fortune: Allah Wills It</b>','
no_pass_phrase = """<p>Sorry whiteboy, we're gonna need to see some ID before you start throwin that word around like it's nothing.\n\nTake a 10 minute time-out and come back when you've learned your lesson and/or paid reparations (by purchasing a BIPOC Approved™ rDrama NWord Pass© from the <a href="/shop">shop</a>) \n\n<em>This is an automated message; if you need help, you can message us <a href="/contact">here</a>.</em></p>"""
db = db_session()
SUBS = [x[0] for x in db.query(Sub.name).all()]
db.close()
ROLES={
"owner": "864612849199480914",
"admin": "879459632656048180" if environ.get("DOMAIN") == "pcmemes.net" else "846509661288267776",
@ -600,4 +596,6 @@ REDDIT_NOTIFS = {
'carpathianflorist': CARP_ID,
'carpathian florist': CARP_ID,
'the_homocracy': HOMO_ID
}
}
toomuch_subs = ('2much4you','2balkan4you','2middleeast4you','2asia4you','2caucasian4you','2european4you','2american4you')

View File

@ -32,9 +32,7 @@ def get_user(username, v=None, graceful=False):
if not graceful: abort(404)
else: return None
username = username.replace('\\', '')
username = username.replace('_', '\_')
username = username.replace('%', '')
username = username.replace('\\', '').replace('_', '\_').replace('%', '').strip()
user = g.db.query(
User

View File

@ -16,4 +16,4 @@ def post_embed(id, v):
@app.context_processor
def inject_constants():
return {"environ":environ, "SITE":SITE, "SITE_NAME":SITE_NAME, "SITE_FULL":SITE_FULL, "AUTOJANNY_ID":AUTOJANNY_ID, "NOTIFICATIONS_ID":NOTIFICATIONS_ID, "PUSHER_ID":PUSHER_ID, "CC":CC, "CC_TITLE":CC_TITLE, "listdir":listdir, "MOOSE_ID":MOOSE_ID, "AEVANN_ID":AEVANN_ID, "config":app.config.get, "DEFAULT_COLOR":DEFAULT_COLOR, "COLORS":COLORS, "SUBS": SUBS}
return {"environ":environ, "SITE":SITE, "SITE_NAME":SITE_NAME, "SITE_FULL":SITE_FULL, "AUTOJANNY_ID":AUTOJANNY_ID, "NOTIFICATIONS_ID":NOTIFICATIONS_ID, "PUSHER_ID":PUSHER_ID, "CC":CC, "CC_TITLE":CC_TITLE, "listdir":listdir, "MOOSE_ID":MOOSE_ID, "AEVANN_ID":AEVANN_ID, "config":app.config.get, "DEFAULT_COLOR":DEFAULT_COLOR, "COLORS":COLORS}

View File

@ -14,4 +14,5 @@ from .users import *
from .votes import *
from .feeds import *
from .awards import *
from .giphy import *
from .giphy import *
from .subs import *

View File

@ -340,42 +340,6 @@ def post_sidebar(v):
return render_template('admin/sidebar.html', v=v, sidebar=sidebar, msg='Sidebar edited successfully!')
@app.get('/s/<sub>/sidebar')
@auth_required
def get_sub_sidebar(v, sub):
sub = g.db.query(Sub).filter_by(name=sub).one_or_none()
if not sub: abort(404)
if not v.mods(sub.name): abort(403)
return render_template('admin/sidebar.html', v=v, sidebar=sub.sidebar, sub=sub)
@app.post('/s/<sub>/sidebar')
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@auth_required
def post_sub_sidebar(v, sub):
sub = g.db.query(Sub).filter_by(name=sub).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_html = sanitize(sub.sidebar)
g.db.add(sub)
ma = ModAction(
kind="change_sidebar",
user_id=v.id
)
g.db.add(ma)
g.db.commit()
return render_template('admin/sidebar.html', v=v, sidebar=sub.sidebar, msg='Sidebar edited successfully!', sub=sub)
@app.get("/admin/shadowbanned")
@auth_required
def shadowbanned(v):

View File

@ -133,7 +133,7 @@ def notifications(v):
@limiter.limit("3/second;30/minute;400/hour;2000/day")
@auth_desired
def front_all(v, sub=None):
if sub: sub = g.db.query(Sub).filter_by(name=sub).one_or_none()
if sub: sub = g.db.query(Sub).filter_by(name=sub..strip().lower()).one_or_none()
if request.path.startswith('/s/') and not sub: abort(404)
@ -151,11 +151,11 @@ def front_all(v, sub=None):
if v:
defaultsorting = v.defaultsorting
if sub or SITE_NAME == '2Much4You': defaulttime = 'all'
if sub or SITE_NAME != 'Drama': defaulttime = 'all'
else: defaulttime = v.defaulttime
else:
defaultsorting = "hot"
if sub or SITE_NAME == '2Much4You': defaulttime = 'all'
if sub or SITE_NAME != 'Drama': defaulttime = 'all'
else: defaulttime = defaulttimefilter
sort=request.values.get("sort", defaultsorting)
@ -268,7 +268,8 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, ccmode="false"
posts = g.db.query(Submission)
if sub: posts = posts.filter_by(sub=sub.name)
elif SITE_NAME == '2Much4You': posts = posts.filter(Submission.sub != None)
elif SITE_NAME == '2Much4You': posts = posts.filter(Submission.sub.in_(toomuch_subs))
elif SITE_NAME == 'ruqqus': posts = posts.filter(Submission.sub != None)
else: posts = posts.filter_by(sub=None)
if gt: posts = posts.filter(Submission.created_utc > gt)
@ -343,7 +344,8 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, ccmode="false"
if (sort == "hot" or (v and v.id == Q_ID)) and page == 1 and ccmode == "false" and not gt and not lt:
pins = g.db.query(Submission).filter(Submission.stickied != None, Submission.is_banned == False)
if sub: pins = pins.filter_by(sub=sub.name)
elif SITE_NAME == '2Much4You': pins = pins.filter(Submission.sub != None)
elif SITE_NAME == '2Much4You': pins = pins.filter(Submission.sub.in_(toomuch_subs))
elif SITE_NAME == 'ruqqus': pins = pins.filter(Submission.sub != None)
else: pins = pins.filter_by(sub=None)
if v and v.admin_level == 0:

View File

@ -91,11 +91,11 @@ def publish(pid, v):
@app.get("/s/<sub>/submit")
@auth_required
def submit_get(v, sub=None):
if sub: sub = g.db.query(Sub.name).filter_by(name=sub).one_or_none()
if sub: sub = g.db.query(Sub.name).filter_by(name=sub.strip().lower()).one_or_none()
if request.path.startswith('/s/') and not sub: abort(404)
return render_template("submit.html", v=v, sub=sub)
return render_template("submit.html", SUBS=tuple(x[0] for x in g.db.query(Sub.name).all()) if SITE_NAME == 'Drama' else None, v=v, sub=sub)
@app.get("/post/<pid>")
@app.get("/post/<pid>/<anything>")
@ -804,7 +804,7 @@ def thumbnail_thread(pid):
@auth_required
def submit_post(v, sub=None):
if not sub: sub = request.values.get("sub")
sub = g.db.query(Sub.name).filter_by(name=sub).one_or_none()
sub = g.db.query(Sub.name).filter_by(name=sub.strip().lower()).one_or_none()
if sub: sub = sub[0]
else: sub = None
@ -879,7 +879,7 @@ def submit_post(v, sub=None):
if domain_obj:
reason = f"Remove the {domain_obj.domain} link from your post and try again. {domain_obj.reason}"
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error":reason}, 400
return render_template("submit.html", v=v, error=reason, title=title, url=url, body=request.values.get("body", "")), 400
return render_template("submit.html", SUBS=tuple(x[0] for x in g.db.query(Sub.name).all()) if SITE_NAME == 'Drama' else None, v=v, error=reason, title=title, url=url, body=request.values.get("body", "")), 400
elif "twitter.com" == domain:
try: embed = requests.get("https://publish.twitter.com/oembed", timeout=5, params={"url":url, "omit_script":"t"}).json()["html"]
except: embed = None
@ -901,16 +901,16 @@ def submit_post(v, sub=None):
if not url and not request.values.get("body") and not request.files.get("file", None):
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "`url` or `body` parameter required."}, 400
return render_template("submit.html", v=v, error="Please enter a url or some text.", title=title, url=url, body=request.values.get("body", "")), 400
return render_template("submit.html", SUBS=tuple(x[0] for x in g.db.query(Sub.name).all()) if SITE_NAME == 'Drama' else None, v=v, error="Please enter a url or some text.", title=title, url=url, body=request.values.get("body", "")), 400
if not title:
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "Please enter a better title"}, 400
return render_template("submit.html", v=v, error="Please enter a better title.", title=title, url=url, body=request.values.get("body", "")), 400
return render_template("submit.html", SUBS=tuple(x[0] for x in g.db.query(Sub.name).all()) if SITE_NAME == 'Drama' else None, v=v, error="Please enter a better title.", title=title, url=url, body=request.values.get("body", "")), 400
elif len(title) > 500:
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "500 character limit for titles"}, 400
else: render_template("submit.html", v=v, error="500 character limit for titles.", title=title[:500], url=url, body=request.values.get("body", "")), 400
else: render_template("submit.html", SUBS=tuple(x[0] for x in g.db.query(Sub.name).all()) if SITE_NAME == 'Drama' else None, v=v, error="500 character limit for titles.", title=title[:500], url=url, body=request.values.get("body", "")), 400
if v.marseyawarded:
marregex = list(re.finditer("^(:[!#]{0,2}m\w+:\s*)+$", title, re.A))
@ -979,12 +979,12 @@ def submit_post(v, sub=None):
if len(str(body)) > 20000:
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error":"There's a 20000 character limit for text body."}, 400
return render_template("submit.html", v=v, error="There's a 20000 character limit for text body.", title=title, url=url, body=request.values.get("body", "")), 400
return render_template("submit.html", SUBS=tuple(x[0] for x in g.db.query(Sub.name).all()) if SITE_NAME == 'Drama' else None, v=v, error="There's a 20000 character limit for text body.", title=title, url=url, body=request.values.get("body", "")), 400
if len(url) > 2048:
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error":"2048 character limit for URLs."}, 400
return render_template("submit.html", v=v, error="2048 character limit for URLs.", title=title, url=url,body=request.values.get("body", "")), 400
return render_template("submit.html", SUBS=tuple(x[0] for x in g.db.query(Sub.name).all()) if SITE_NAME == 'Drama' else None, v=v, error="2048 character limit for URLs.", title=title, url=url,body=request.values.get("body", "")), 400
for i in re.finditer('^(https:\/\/.*\.(png|jpg|jpeg|gif|webp|PNG|JPG|JPEG|GIF|WEBP|9999)($|\s|\n))', body, re.M|re.A):
if "wikipedia" not in i.group(1): body = body.replace(i.group(1), f'![]({i.group(1)})')
@ -1022,7 +1022,7 @@ def submit_post(v, sub=None):
body += f"\n\n{url}"
else:
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "Image/Video files only"}, 400
return render_template("submit.html", v=v, error="Image/Video files only."), 400
return render_template("submit.html", SUBS=tuple(x[0] for x in g.db.query(Sub.name).all()) if SITE_NAME == 'Drama' else None, v=v, error="Image/Video files only."), 400
if '#fortune' in body:
body = body.replace('#fortune', '')
@ -1045,7 +1045,7 @@ def submit_post(v, sub=None):
reason = f"Remove the {ban.domain} link from your post and try again."
if ban.reason: reason += f" {ban.reason}"
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": reason}, 403
return render_template("submit.html", v=v, error=reason, title=title, url=url, body=request.values.get("body", "")), 403
return render_template("submit.html", SUBS=tuple(x[0] for x in g.db.query(Sub.name).all()) if SITE_NAME == 'Drama' else None, v=v, error=reason, title=title, url=url, body=request.values.get("body", "")), 403
if v.club_allowed == False: club = False
else: club = bool(request.values.get("club",""))
@ -1131,7 +1131,7 @@ def submit_post(v, sub=None):
new_post.url = url
else:
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "File type not allowed"}, 400
return render_template("submit.html", v=v, error="File type not allowed.", title=title, body=request.values.get("body", "")), 400
return render_template("submit.html", SUBS=tuple(x[0] for x in g.db.query(Sub.name).all()) if SITE_NAME == 'Drama' else None, v=v, error="File type not allowed.", title=title, body=request.values.get("body", "")), 400
if not new_post.thumburl and new_post.url:

View File

@ -0,0 +1,204 @@
from files.__main__ import app, limiter, mail
from files.helpers.alerts import *
from files.helpers.wrappers import *
from files.classes import *
from .front import frontlist
valid_sub_regex = re.compile("^[a-zA-Z0-9_\-]{3,25}$")
@app.get("/s/<sub>/mods")
@auth_required
def mods(v, sub):
sub = g.db.query(Sub).filter_by(name=sub.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()
return render_template("sub/mods.html", v=v, sub=sub, users=users)
@app.post("/s/<sub>/add_mod")
@auth_required
def add_mod(v, sub):
sub = g.db.query(Sub).filter_by(name=sub.lower()).one_or_none()
if not sub: abort(404)
sub = sub.name
if not v.mods(sub): abort(403)
user = request.values.get('user')
if not user: abort(400)
user = get_user(user)
mod = Mod(user_id=user.id, sub=sub)
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.get("/create_sub")
@auth_required
def create_sub(v):
return render_template("sub/create_sub.html", v=v)
@app.post("/create_sub")
@auth_required
def create_sub2(v):
name = request.values.get('name')
if not name: abort(400)
name = name.strip().lower()
if not re.fullmatch(valid_sub_regex, name):
return render_template("sub/create_sub.html", v=v, error="Sub name not allowed."), 400
sub = g.db.query(Sub).filter_by(name=name).one_or_none()
if not sub:
cost = v.subs_created * 25
if v.coins < cost:
return render_template("sub/create_sub.html", v=v, error="You don't have enough coins!"), 403
v.coins -= cost
v.subs_created += 1
g.db.add(v)
sub = Sub(name=name)
g.db.add(sub)
mod = Mod(user_id=v.id, sub=sub.name)
g.db.add(mod)
g.db.commit()
return redirect(f'/s/{sub.name}')
@app.post("/kick/<pid>")
@auth_required
def kick(v, pid):
try: pid = int(pid)
except: abort(400)
post = get_post(pid)
if not post.sub: abort(403)
if not v.mods(post.sub): abort(403)
post.sub = 'general'
g.db.add(post)
g.db.commit()
cache.delete_memoized(frontlist)
return {"message": "Post kicked successfully!"}
@app.get('/s/<sub>/settings')
@auth_required
def sub_settings(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)
return render_template('sub/settings.html', v=v, sidebar=sub.sidebar, sub=sub)
@app.post('/s/<sub>/sidebar')
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@auth_required
def post_sub_sidebar(v, sub):
sub = g.db.query(Sub).filter_by(name=sub.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_html = sanitize(sub.sidebar)
g.db.add(sub)
ma = ModAction(
kind="change_sidebar",
user_id=v.id
)
g.db.add(ma)
g.db.commit()
return redirect(f'/s/{sub.name}/settings')
@app.post("/s/<sub>/banner")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@auth_required
def sub_banner(v, sub):
if v and v.patron:
if request.content_length > 8 * 1024 * 1024: return {"error":"Max file size is 8 MB."}, 413
elif request.content_length > 4 * 1024 * 1024: return {"error":"Max file size is 4 MB."}, 413
if request.headers.get("cf-ipcountry") == "T1": return {"error":"Image uploads are not allowed through TOR."}, 403
sub = g.db.query(Sub).filter_by(name=sub.lower().strip()).one_or_none()
if not sub: abort(404)
if not v.mods(sub.name): abort(403)
file = request.files["banner"]
name = f'/images/{time.time()}'.replace('.','')[:-5] + '.webp'
file.save(name)
bannerurl = process_image(name)
if bannerurl:
if sub.bannerurl and '/images/' in sub.bannerurl:
fpath = '/images/' + sub.bannerurl.split('/images/')[1]
if path.isfile(fpath): os.remove(fpath)
sub.bannerurl = bannerurl
g.db.add(sub)
g.db.commit()
return redirect(f'/s/{sub.name}/settings')
@app.post("/s/<sub>/sidebar_image")
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@auth_required
def sub_sidebar(v, sub):
if v and v.patron:
if request.content_length > 8 * 1024 * 1024: return {"error":"Max file size is 8 MB."}, 413
elif request.content_length > 4 * 1024 * 1024: return {"error":"Max file size is 4 MB."}, 413
if request.headers.get("cf-ipcountry") == "T1": return {"error":"Image uploads are not allowed through TOR."}, 403
sub = g.db.query(Sub).filter_by(name=sub.lower().strip()).one_or_none()
if not sub: abort(404)
if not v.mods(sub.name): abort(403)
file = request.files["sidebar"]
name = f'/images/{time.time()}'.replace('.','')[:-5] + '.webp'
file.save(name)
sidebarurl = process_image(name)
if sidebarurl:
if sub.sidebarurl and '/images/' in sub.sidebarurl:
fpath = '/images/' + sub.sidebarurl.split('/images/')[1]
if path.isfile(fpath): os.remove(fpath)
sub.sidebarurl = sidebarurl
g.db.add(sub)
g.db.commit()
return redirect(f'/s/{sub.name}/settings')
#create general
#subs urls
#-----
#mods id seq
#css
#exile
#guild mod log
#remove mod
#search sub

View File

@ -20,7 +20,7 @@
<div class="col col-md-8">
<div class="settings">
<div id="description">
<h2>Edit {% if sub %}/s/{{sub.name}}{% endif %} sidebar</h2>
<h2>Edit Sidebar</h2>
<br>
</div>
<div class="body d-lg-flex">

View File

@ -231,7 +231,9 @@
{% if c.author.verified %}<i class="fas fa-badge-check align-middle ml-1" style="color:{% if c.author.verifiedcolor %}#{{c.author.verifiedcolor}}{% else %}#1DA1F2{% endif %}" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="{{c.author.verified}}"></i>
{% endif %}
{% if not c.author %}
{{c.print()}}
{% endif %}
<a class="user-name text-decoration-none" onclick='popclick({{c.author.json_popover(v) | tojson}})' data-bs-placement="bottom" data-bs-toggle="popover" data-bs-trigger="click" data-content-id="popover" role="button" tabindex="0" style="color:#{{c.author.namecolor}}; font-size:12px; font-weight:bold;"><img alt="@{{c.author_name}}'s profile picture" loading="lazy" src="{{c.author.profile_url}}" class="profile-pic-25 mr-2"><span {% if c.author.patron and not c.distinguish_level %}class="patron" style="background-color:#{{c.author.namecolor}};"{% elif c.distinguish_level and SITE_NAME == 'Drama' %}class="mod"{% endif %}>{{c.author_name}}</span></a>
{% if c.author.customtitle %}&nbsp;<bdi style="color: #{{c.author.titlecolor}}">&nbsp;{% if c.author.quadrant %}<img alt="{{c.author.quadrant}} quadrant" loading="lazy" height="20" src="/static/assets/images/quadrants/{{c.author.quadrant}}.webp?a=1008">{% endif %}{{c.author.customtitle | safe}}</bdi>{% endif %}
{% endif %}

View File

@ -223,6 +223,10 @@
<a href="https://naacp.org/donate">
<img alt="site banner" src="{{image}}" width="100%">
</a>
{% elif sub %}
<a href="/">
<img alt="sub banner" src="{{sub.banner_url}}" height=100 width=100% style="object-fit:cover">
</a>
{% else %}
<a href="/">
<img alt="site banner" src="/static/assets/images/{{SITE_NAME}}/banner.webp?a=1012" width="100%">

View File

@ -8,6 +8,13 @@
<li class="nav-item">
<a class="nav-link active emojitab" data-bs-toggle="tab" href="#emoji-tab-favorite">Favorite</a>
</li>
{% if SITE_NAME == 'ruqqus' %}
<li class="nav-item">
<a class="nav-link emojitab" data-bs-toggle="tab" href="#emoji-tab-ruqqie">Ruqqie</a>
</li>
{% endif %}
<li class="nav-item">
<a class="nav-link emojitab" data-bs-toggle="tab" href="#emoji-tab-marsey">Marsey</a>
</li>
@ -52,6 +59,13 @@
<div class="tab-pane fade show active" id="emoji-tab-favorite">
<div class="d-flex flex-wrap py-3 pl-2" id="EMOJIS_favorite"></div>
</div>
{% if SITE_NAME == 'ruqqus' %}
<div class="tab-pane fade" id="emoji-tab-ruqqie">
<div class="d-flex flex-wrap py-3 pl-2" id="EMOJIS_ruqqie"></div>
</div>
{% endif %}
<div class="tab-pane fade" id="emoji-tab-marsey">
<div class="d-flex flex-wrap py-3 pl-2" id="EMOJIS_marsey"></div>
</div>
@ -86,7 +100,7 @@
</div>
</div>
<script data-cfasync="false" src="/static/assets/js/emoji_modal.js?a=242"></script>
<script data-cfasync="false" src="/static/assets/js/emoji_modal.js?a=243"></script>
<style>
a.emojitab {

View File

@ -1,6 +1,6 @@
<nav class="shadow shadow-md fixed-top">
{% if SITE_NAME == 'Drama' or SUBS %}
{% if SITE_NAME == 'Drama' %}
<style>
body {padding-top: 85.88px !important}
@media (max-width: 767.98px) {
@ -24,14 +24,6 @@
<div class="srd">
<a style="color: white" class="text-small-mobile" href="https://reddit.com/r/SubredditDrama">💖🌈 welcome to {{SITE}}: the official site for r/subredditdrama</a>
</div>
{% elif SUBS %}
<div class="srd">
{% for s in SUBS %}
{% if s != 'general' %}
<a {% if sub and s == sub.name %} style="color: var(--secondary)" {% else %} style="color: white"{% endif %} class="text-small-mobile ml-2" href="/s/{{s}}">/s/{{s}}</a>
{% endif %}
{% endfor %}
</div>
{% endif %}
@ -168,7 +160,7 @@
{% if request.host != 'pcmemes.net' %}
<a class="dropdown-item" href="/discord"><i class="fab fa-discord fa-fw text-left mr-3"></i>Discord</a>
{% endif %}
{% if not (g.webview and v.truecoins < 1) and request.host != '2Much4You' %}
{% if not (g.webview and v.truecoins < 1) and SITE_NAME not in ('2Much4You','ruqqus') %}
<a class="dropdown-item" rel="nofollow noopener noreferrer" href="{{config('GUMROAD_LINK')}}"><i class="fas fa-dollar-sign fa-fw text-left mr-3"></i>Donate</a>
{% endif %}
{% if SITE_NAME == 'Drama' %}<a class="dropdown-item" href="/archives"><i class="fas fa-book fa-fw text-left mr-3"></i>Archives</a>{% endif %}
@ -223,7 +215,7 @@
{% if request.host != 'pcmemes.net' %}
<a class="nav-item nav-link" href="/discord"><i class="fab fa-discord fa-fw mr-3"></i>Discord</a>
{% endif %}
{% if not (g.webview and v.truecoins < 1) %}
{% if not (g.webview and v.truecoins < 1) and SITE_NAME not in ('2Much4You','ruqqus') %}
<a class="nav-item nav-link" rel="nofollow noopener noreferrer" href="{{config('GUMROAD_LINK')}}"><i class="fas fa-dollar-sign fa-fw mr-3"></i>Donate</a>
{% endif %}
{% if SITE_NAME == 'Drama' %}<a class="nav-item nav-link" href="/archives"><i class="fas fa-book fa-fw mr-3"></i>Archives</a>{% endif %}

View File

@ -1,6 +1,6 @@
<div class="col sidebar text-left d-none d-lg-block pt-3 bg-white" style="max-width:300px">
{% if sub %}
{% set image='/static/assets/images/subs/' + sub.name + '.webp?a=1010' %}
{% set image=sub.sidebar_url %}
{% else %}
{% set image='/static/assets/images/2Much4You/sidebar.webp?a=1039' %}
{% endif %}
@ -9,10 +9,12 @@
{% if sub %}
<div class="mt-4">{{sub.sidebar_html|safe}}</div>
{% if sub.sidebar_html %}
<div class="mt-4">{{sub.sidebar_html|safe}}</div>
{% endif %}
<a class="btn btn-primary btn-block mt-4" href="/s/{{sub.name}}/mods">MODS</a>
{% if v and v.mods(sub.name) %}
<a class="btn btn-primary btn-block" href="/s/{{sub.name}}/sidebar">EDIT SIDEBAR</a>
<a class="btn btn-primary btn-block" href="/s/{{sub.name}}/settings">SUB SETTINGS</a>
{% endif %}
{% else %}
<p class="mt-4">Rules: No doxxing, No CP or other clearly illegal shit. Thanks!</p>

View File

@ -1,7 +1,7 @@
<div class="col sidebar text-left d-none d-lg-block pt-3 pb-5 bg-white" style="max-width:300px">
{% if sub %}
{% set image='/static/assets/images/subs/' + sub.name + '.webp?a=1010' %}
{% set image=sub.sidebar_url %}
{% else %}
{% set path = "assets/images/" + SITE_NAME + "/sidebar" %}
{% set image = "/static/" + path + "/" + listdir('files/' + path)|random() + '?a=32' %}
@ -12,10 +12,12 @@
</a>
{% if sub %}
<div class="mt-4">{{sub.sidebar_html|safe}}</div>
{% if sub.sidebar_html %}
<div class="mt-4">{{sub.sidebar_html|safe}}</div>
{% endif %}
<a class="btn btn-primary btn-block mt-4" href="/s/{{sub.name}}/mods">MODS</a>
{% if v and v.mods(sub.name) %}
<a class="btn btn-primary btn-block" href="/s/{{sub.name}}/sidebar">EDIT SIDEBAR</a>
<a class="btn btn-primary btn-block" href="/s/{{sub.name}}/settings">SUB SETTINGS</a>
{% endif %}
{% else %}
<a class="btn btn-primary btn-block mt-4" href="/post/16583">EMOJI MEGATHREAD</a>

View File

@ -4,7 +4,7 @@
<a class="btn btn-primary btn-block mt-4" href="https://ip2.network">STREAM LIST</a>
<a class="btn btn-primary btn-block" href="/post/4103">BUGS/SUGGESTIONS MEGATHREAD</a>
<p class="mt-4">Rules: No doxxing, No CP or other clearly illegal shit. Thanks.</p>
<p class="mt-4">Rules: No doxxing, No CP or other clearly illegal shit. Thanks!</p>
<pre>

View File

@ -0,0 +1,31 @@
<div class="col sidebar text-left d-none d-lg-block pt-3 bg-white" style="max-width:300px">
{% if sub %}
{% set image=sub.sidebar_url %}
{% else %}
{% 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%>
<a class="btn btn-primary btn-block mt-4" href="/create_sub">CREATE SUB</a>
{% if sub %}
{% if sub.sidebar_html %}
<div class="mt-4">{{sub.sidebar_html|safe}}</div>
{% endif %}
<a class="btn btn-primary btn-block" href="/s/{{sub.name}}/mods">MODS</a>
{% if v and v.mods(sub.name) %}
<a class="btn btn-primary btn-block" href="/s/{{sub.name}}/settings">SUB SETTINGS</a>
{% endif %}
{% else %}
<p class="mt-4">Rules: No doxxing, No CP or other clearly illegal shit. Thanks!</p>
{% endif %}
<pre>
</pre>
</div>

View File

@ -0,0 +1,62 @@
{% extends "submit.html" %}
{% block title %}
<title>Create a Sub</title>
{% endblock %}
{% block form %}
<pre>
</pre>
<form id="submitform" action="/create_sub" method="post">
<div class="container">
<div class="row justify-content-center mb-4 pb-7">
<div class="col col-md-6 p-3 py-md-0">
<h1 class="d-none d-md-block">Create a sub</h1>
<h2 class="h3 d-md-none">Create a sub</h2>
<div class="body">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<label for="title">Sub Name</label>
<input class="form-control" id="title-register" aria-describedby="titleHelpRegister" type="text" name="name" required>
<small class="form-text text-muted">Names must be 3-25 characters</small>
</div>
<div class="footer">
<div class="d-flex">
{% if error %}
<p class="mb-0">
<span class="text-danger text-small" style="vertical-align: sub;">{{ error }}</span>
</p>
{% endif %}
<button class="btn btn-primary ml-auto" id="create_button" {% if v.subs_created * 25 > v.coins %}disabled{% endif %}>Create Sub</button>
</div>
<p class="mt-2 mr-1" style="float: right"><b>Cost</b>: {{v.subs_created * 25}} coins</p>
</div>
</div>
</div>
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,33 @@
{% extends "default.html" %}
{% block content %}
<pre>
</pre>
<h5>/s/{{sub.name}} Mods</h5>
<pre></pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white">
<tr>
<th style="font-weight: bold">#</th>
<th style="font-weight: bold">Name</th>
</tr>
</thead>
{% for user 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>
</tr>
{% endfor %}
</table>
{% if v.mods(sub) %}
<form action="/s/{{sub.name}}/add_mod" method="post">
<input autocomplete="off" type="hidden" name="formkey" value="{{v.formkey}}" >
<input class="form-control" style="display:inline;width:25%" autocomplete="off" type="text" name="user" class="form-control" placeholder="Enter username..">
<input class="btn btn-primary" style="margin-top:-5px" autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Add Mod">
</form>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,110 @@
{% extends "default.html" %}
{% block pagetitle %}Edit {{SITE_NAME}} sidebar{% endblock %}
{% block content %}
{% if msg %}
<div class="alert alert-success alert-dismissible fade show my-3" role="alert">
<i class="fas fa-check-circle my-auto" aria-hidden="true"></i>
<span>
{{msg}}
</span>
<button class="close" data-bs-dismiss="alert" aria-label="Close">
<span aria-hidden="true"><i class="far fa-times"></i></span>
</button>
</div>
{% endif %}
<h2 class="h5 mt-5">Sidebar Picture</h2>
<div class="settings-section rounded">
<div class="d-flex">
<div class="title w-lg-25 text-md-center">
<img loading="lazy" alt="sub sidebar picture" src="{{sub.sidebar_url}}" class="profile-pic-75">
</div>
<div class="body w-lg-100 my-auto">
<div class="d-flex">
<div>
<form action="/s/{{sub.name}}/sidebar_image" method="post" enctype="multipart/form-data">
<input autocomplete="off" type="hidden" name="formkey" value="{{v.formkey}}">
<label class="btn btn-secondary text-capitalize mr-2 mb-0">
Update<input autocomplete="off" type="file" accept="image/*" {% if request.headers.get('cf-ipcountry')=="T1" %}disabled{% endif %} hidden name="sidebar" onchange="form.submit()">
</label>
</form>
</div>
</div>
<div class="text-small-extra text-muted mt-3">JPG, PNG, GIF files are supported. Max file size is {% if v and v.patron %}8{% else %}4{% endif %} MB.</div>
</div>
</div>
</div>
<h2 class="h5 mt-5">Banner</h2>
<div class="settings-section rounded">
<div class="d-flex">
<div class="title w-lg-75 text-md-center">
<img loading="lazy" alt="sub banner" src="{{sub.banner_url}}" class="banner-pic-135">
</div>
<div class="body w-lg-100 my-auto">
<div class="d-flex">
<div>
<form action="/s/{{sub.name}}/banner" method="post" enctype="multipart/form-data">
<input autocomplete="off" type="hidden" name="formkey" value="{{v.formkey}}">
<label class="btn btn-secondary text-capitalize mr-2 mb-0">
Update<input autocomplete="off" type="file" {% if request.headers.get('cf-ipcountry')=="T1" %}disabled{% endif %} accept="image/*" hidden name="banner" onchange="form.submit()">
</label>
</form>
</div>
</div>
<div class="text-small-extra text-muted mt-3">JPG, PNG, GIF files are supported. Max file size is {% if v and v.patron %}8{% else %}4{% endif %} MB.</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 Sidebar</h2>
<br>
</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">
<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>
<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>
{% endblock %}

View File

@ -335,6 +335,10 @@
<button id="block2-{{p.id}}" class="blockuser nobackground btn btn-link btn-block btn-lg text-danger text-left{% if p.is_blocking %} d-none{% endif %}" onclick="document.getElementById('block2-{{p.id}}').classList.toggle('d-none');document.getElementById('prompt2-{{p.id}}').classList.toggle('d-none');"><i class="fas fa-eye-slash mr-3 text-danger"></i>Block user</button>
{% endif %}
{% endif %}
{% if p.sub and v.mods(p.sub) %}
<button class="nobackground btn btn-link btn-block btn-lg text-left text-danger" onclick="post_toast('/kick/{{p.id}}')"><i class="fas fa-sign-out text-danger text-center mr-3"></i>Kick</button>
{% endif %}
</ul>
</div>
</div>
@ -445,6 +449,11 @@
{% if p.over_18 %}<span class="badge badge-danger text-small-extra mr-1">+18</span>{% endif %}
{% if p.private %}<span class="badge border-warning border-1 text-small-extra">Draft</span>{% endif %}
{% if p.active_flags %}<a class="btn btn-primary" role="button" style="padding:1px 5px; font-size:10px;" onclick="document.getElementById('flaggers').classList.toggle('d-none')">{{p.active_flags}} Reports</a>{% endif %}
{% if not p.author %}
{{p.print()}}
{% endif %}
{% if p.ghost %}
👻
{% else %}
@ -616,7 +625,7 @@
{% endif %}
{% if not p.ghost %}<a class="list-inline-item" href="/votes?link={{p.fullname}}"><i class="fas fa-arrows-v"></i>Votes</a>{% endif %}
{% if v %}
<a class="list-inline-item text-muted d-none d-md-inline-block" role="button" data-bs-toggle="modal" data-bs-target="#awardModal" onclick="awardModal('/post/{{p.id}}/awards')"><i class="fas fa-gift fa-fw"></i>Give Award</a>
{% endif %}
@ -687,6 +696,10 @@
<a id="block-{{p.id}}" class="text-danger blockuser list-inline-item {% if p.is_blocking %} d-none{% endif %}" role="button" onclick="document.getElementById('block-{{p.id}}').classList.toggle('d-none');document.getElementById('prompt-{{p.id}}').classList.toggle('d-none');"><i class="fas fa-eye-slash text-danger"></i>Block user</a>
{% endif %}
{% if p.sub and v.mods(p.sub) %}
<a class="list-inline-item text-danger" role="button" onclick="post_toast('/kick/{{p.id}}')"><i class="fas fa-sign-out text-danger"></i>Kick</a>
{% endif %}
{% if v.admin_level > 1 and v.id!=p.author_id %}
<a id="ban-{{p.id}}" class="{% if p.author.is_suspended %}d-none{% endif %} list-inline-item text-danger" role="button" data-bs-toggle="modal" data-bs-target="#banModal" onclick="banModal('/post/{{p.id}}', '{{p.author.id}}', '{{p.author_name}}')"><i class="fas fa-user-slash text-danger fa-fw"></i>Ban user</a>
<a id="unban-{{p.id}}" class="{% if not p.author.is_suspended %}d-none{% endif %} list-inline-item text-danger" id="unexile2-user-{{p.id}}" role="button" onclick="post_toast2('/unban_user/{{p.author_id}}','ban-{{p.id}}','unban-{{p.id}}')"><i class="fas fa-user-slash"></i>Unban user</a>

View File

@ -181,6 +181,11 @@
{% if p.is_blocked %}<i class="fas fa-user-minus text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-original-title="This user is blocking you."></i>{% endif %}
{% if p.private %}<span class="badge border-warning border-1 text-small-extra">Draft</span>{% endif %}
{% if p.active_flags %}<a class="btn btn-primary" role="button" style="padding:1px 5px; font-size:10px;" onclick="document.getElementById('flaggers-{{p.id}}').classList.toggle('d-none')">{{p.active_flags}} Reports</a>{% endif %}
{% if not p.author %}
{{p.print()}}
{% endif %}
{% if p.ghost %}
👻
{% else %}
@ -289,6 +294,12 @@
<a id="block-{{p.id}}" class="dropdown-item list-inline-item text-danger {% if p.is_blocking %}d-none{% endif %}" role="button" onclick="post_toast2('/settings/block?username={{p.author_name}}','block-{{p.id}}','unblock-{{p.id}}')"><i class="fas fa-eye-slash text-danger"></i>Block user</a>
{% endif %}
{% if p.sub and v.mods(p.sub) %}
<a class="list-inline-item text-danger" role="button" onclick="post_toast('/kick/{{p.id}}')"><i class="fas fa-sign-out text-danger"></i>Kick</a>
{% endif %}
{% if v.id==p.author_id or v.admin_level > 1 %}
<a id="mark-{{p.id}}" class="dropdown-item {% if p.over_18 %}d-none{% endif %} list-inline-item text-danger" role="button" onclick="post_toast2('/toggle_post_nsfw/{{p.id}}','mark-{{p.id}}','unmark-{{p.id}}')"><i class="fas fa-eye-evil"></i>Mark +18</a>
<a id="unmark-{{p.id}}" class="dropdown-item {% if not p.over_18 %}d-none{% endif %} list-inline-item text-success" role="button" onclick="post_toast2('/toggle_post_nsfw/{{p.id}}','mark-{{p.id}}','unmark-{{p.id}}')"><i class="fas fa-eye-evil"></i>Unmark +18</a>
@ -442,6 +453,10 @@
<button id="prompt2-{{p.id}}" class="blockuser nobackground btn btn-link btn-block btn-lg text-danger text-left d-none" data-bs-dismiss="modal" onclick="post_toast2('/settings/block?username={{p.author_name}}','prompt2-{{p.id}}','unblock2-{{p.id}}')"><i class="fas fa-eye-slash mr-3"></i>Are you sure?</button>
<button id="block2-{{p.id}}" class="blockuser nobackground btn btn-link btn-block btn-lg text-danger text-left{% if p.is_blocking %} d-none{% endif %}" onclick="document.getElementById('block2-{{p.id}}').classList.toggle('d-none');document.getElementById('prompt2-{{p.id}}').classList.toggle('d-none');"><i class="fas fa-eye-slash mr-3"></i>Block user</button>
{% endif %}
{% if p.sub and v.mods(p.sub) %}
<button class="nobackground btn btn-link btn-block btn-lg text-left text-danger" onclick="post_toast('/kick/{{p.id}}')"><i class="fas fa-sign-out text-danger text-center mr-3"></i>Kick</button>
{% endif %}
</ul>
</div>
</div>

View File

@ -79,7 +79,7 @@
<input autocomplete="off" type="hidden" name="formkey" value="{{v.formkey}}">
{% if SITE_NAME=='2Much4You' %}
{% if SITE_NAME != 'Drama' %}
<label class='mt-4' for="title">Sub</label>
<div class="input-group mb2">