diff --git a/docker-compose.yml b/docker-compose.yml index 935a2e48ba..38d404a129 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ services: - "./:/service" environment: - DATABASE_URL=postgresql://postgres@postgres:5432 - - MASTER_KEY=${MASTER_KEY:XuxGqp5NyygJrM24b5gt3YgyvFVGdQnwVDwLzLwpu3eQwY} + - MASTER_KEY=XuxGqp5NyygJrM24b5gt3YgyvFVGdQnwVDwLzLwpu3eQwY - REDIS_URL=redis://redis - DOMAIN=127.0.0.1 - SITE_NAME=Drama diff --git a/files/__main__.py b/files/__main__.py index 2cd233d969..899b23eaad 100644 --- a/files/__main__.py +++ b/files/__main__.py @@ -73,7 +73,7 @@ r=redis.Redis(host=environ.get("REDIS_URL", "redis://127.0.0.1"), decode_respon limiter = Limiter( app, key_func=get_ipaddr, - default_limits=["50/minute"], + default_limits=["3/second;30/minute;100/hour"], headers_enabled=True, strategy="fixed-window" ) diff --git a/files/classes/comment.py b/files/classes/comment.py index bc8a1bb6fa..d0bdf5bfbe 100644 --- a/files/classes/comment.py +++ b/files/classes/comment.py @@ -7,12 +7,14 @@ from sqlalchemy import * from sqlalchemy.orm import relationship from files.__main__ import Base from files.classes.votes import CommentVote -from files.helpers.const import AUTOPOLLER_ACCOUNT, censor_slurs +from files.helpers.const import AUTOPOLLER_ID, censor_slurs from files.helpers.lazy import lazy from .flags import CommentFlag from random import randint site = environ.get("DOMAIN").strip() +if site == 'pcmemes.net': cc = "splash mountain" +else: cc = "country club" class Comment(Base): @@ -78,7 +80,7 @@ class Comment(Base): @property @lazy def options(self): - return [x for x in self.child_comments if x.author_id == AUTOPOLLER_ACCOUNT] + return [x for x in self.child_comments if x.author_id == AUTOPOLLER_ID] def total_poll_voted(self, v): if v: @@ -183,7 +185,7 @@ class Comment(Base): def replies(self): r = self.__dict__.get("replies", None) if r: r = [x for x in r if not x.author.shadowbanned] - if not r and r != []: r = sorted([x for x in self.child_comments if not x.author.shadowbanned and x.author_id != AUTOPOLLER_ACCOUNT], key=lambda x: x.score, reverse=True) + if not r and r != []: r = sorted([x for x in self.child_comments if not x.author.shadowbanned and x.author_id != AUTOPOLLER_ID], key=lambda x: x.score, reverse=True) return r @replies.setter @@ -201,21 +203,21 @@ class Comment(Base): @property def replies3(self): r = self.__dict__.get("replies", None) - if not r and r != []: r = sorted([x for x in self.child_comments if x.author_id != AUTOPOLLER_ACCOUNT], key=lambda x: x.score, reverse=True) + if not r and r != []: r = sorted([x for x in self.child_comments if x.author_id != AUTOPOLLER_ID], key=lambda x: x.score, reverse=True) return r @property @lazy def shortlink(self): - return f"http://{site}/comment/{self.id}" + return f"http://{site}/comment/{self.id}#context" @property @lazy def permalink(self): - if self.post and self.post.club: return f"/comment/{self.id}/" + if self.post and self.post.club: return f"/comment/{self.id}?context=9#context" - if self.post: return f"{self.post.permalink}/{self.id}/" - else: return f"/comment/{self.id}/" + if self.post: return f"{self.post.permalink}/{self.id}?context=9#context" + else: return f"/comment/{self.id}?context=9#context" @property @lazy @@ -302,7 +304,7 @@ class Comment(Base): return data def realbody(self, v): - if self.post and self.post.club and not (v and v.paid_dues): return "
COUNTRY CLUB ONLY
" + if self.post and self.post.club and not (v and v.paid_dues): return f"{cc} ONLY
" body = self.body_html @@ -335,7 +337,7 @@ class Comment(Base): return body def plainbody(self, v): - if self.post and self.post.club and not (v and v.paid_dues): return "COUNTRY CLUB ONLY
" + if self.post and self.post.club and not (v and v.paid_dues): return f"{cc} ONLY
" body = self.body diff --git a/files/classes/mod_logs.py b/files/classes/mod_logs.py index aa9f8af12b..427faeb7cb 100644 --- a/files/classes/mod_logs.py +++ b/files/classes/mod_logs.py @@ -3,6 +3,11 @@ from sqlalchemy.orm import relationship from files.__main__ import Base import time from files.helpers.lazy import lazy +from os import environ + +site = environ.get("DOMAIN").strip() +if site == 'pcmemes.net': cc = "splash mountain" +else: cc = "country club" class ModAction(Base): __tablename__ = "modactions" @@ -77,7 +82,7 @@ class ModAction(Base): @lazy def string(self): - output = ACTIONTYPES[self.kind]["str"].format(self=self) + output = ACTIONTYPES[self.kind]["str"].format(self=self, cc=cc) if self.note: output += f" ({self.note})" @@ -160,12 +165,12 @@ ACTIONTYPES={ "color": "bg-muted", }, "club_allow":{ - "str":'allowed user {self.target_link} into the country club', + "str":'allowed user {self.target_link} into the {cc}', "icon":"fa-user-slash", "color": "bg-danger", }, "club_ban":{ - "str":'disallowed user {self.target_link} from the country club', + "str":'disallowed user {self.target_link} from the {cc}', "icon": "fa-user-slash", "color": "bg-muted", }, diff --git a/files/classes/submission.py b/files/classes/submission.py index 3ae1d7a6c9..9a9dc5a444 100644 --- a/files/classes/submission.py +++ b/files/classes/submission.py @@ -7,7 +7,7 @@ from flask import render_template from sqlalchemy import * from sqlalchemy.orm import relationship from files.__main__ import Base -from files.helpers.const import AUTOPOLLER_ACCOUNT, censor_slurs, TROLLTITLES +from files.helpers.const import AUTOPOLLER_ID, censor_slurs, TROLLTITLES from files.helpers.lazy import lazy from .flags import Flag from .comment import Comment @@ -15,6 +15,8 @@ from flask import g site = environ.get("DOMAIN").strip() site_name = environ.get("SITE_NAME").strip() +if site == 'pcmemes.net': cc = "SPLASH MOUNTAIN" +else: cc = "COUNTRY CLUB" class Submission(Base): __tablename__ = "submissions" @@ -78,7 +80,7 @@ class Submission(Base): @property @lazy def options(self): - return g.db.query(Comment).filter_by(parent_submission = self.id, author_id = AUTOPOLLER_ACCOUNT, level=1) + return g.db.query(Comment).filter_by(parent_submission = self.id, author_id = AUTOPOLLER_ID, level=1) def total_poll_voted(self, v): if v: @@ -317,7 +319,7 @@ class Submission(Base): else: return "" def realbody(self, v): - if self.club and not (v and v.paid_dues): return "COUNTRY CLUB ONLY
" + if self.club and not (v and v.paid_dues): return f"{cc} ONLY
" body = self.body_html body = censor_slurs(body, v) @@ -335,7 +337,7 @@ class Submission(Base): return body def plainbody(self, v): - if self.club and not (v and v.paid_dues): return "COUNTRY CLUB ONLY
" + if self.club and not (v and v.paid_dues): return f"{cc} ONLY
" body = self.body body = censor_slurs(body, v) @@ -346,9 +348,9 @@ class Submission(Base): @lazy def realtitle(self, v): - if self.club and not (v and v.paid_dues) and not (v and v.admin_level == 6): + if self.club and not (v and v.paid_dues) and not (v and v.admin_level > 1): if v: return random.choice(TROLLTITLES).format(username=v.username) - else: return 'COUNTRY CLUB MEMBERS ONLY' + else: return f'{cc} MEMBERS ONLY' elif self.title_html: title = self.title_html else: title = self.title @@ -358,9 +360,9 @@ class Submission(Base): @lazy def plaintitle(self, v): - if self.club and not (v and v.paid_dues) and not (v and v.admin_level == 6): + if self.club and not (v and v.paid_dues) and not (v and v.admin_level > 1): if v: return random.choice(TROLLTITLES).format(username=v.username) - else: return 'COUNTRY CLUB MEMBERS ONLY' + else: return f'{cc} MEMBERS ONLY' else: title = self.title title = censor_slurs(title, v) diff --git a/files/classes/user.py b/files/classes/user.py index 5293778454..1cd03df48b 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -50,6 +50,7 @@ class User(Base): verified = Column(String) verifiedcolor = Column(String) marseyawarded = Column(Integer) + longpost = Column(Integer) email = deferred(Column(String)) css = deferred(Column(String)) profilecss = deferred(Column(String)) @@ -81,12 +82,15 @@ class User(Base): nitter = Column(Boolean) mute = Column(Boolean) unmutable = Column(Boolean) + eye = Column(Boolean) + alt = Column(Boolean) frontsize = Column(Integer, default=25) controversial = Column(Boolean, default=False) bio = deferred(Column(String)) bio_html = Column(String) sig = deferred(Column(String)) sig_html = Column(String) + fp = Column(String) sigs_disabled = Column(Boolean) friends = deferred(Column(String)) friends_html = deferred(Column(String)) @@ -166,7 +170,6 @@ class User(Base): return return_value @property - @lazy def referral_count(self): return len(self.referrals) @@ -178,7 +181,7 @@ class User(Base): @property @lazy def paid_dues(self): - return self.admin_level == 6 or self.club_allowed or (self.truecoins > int(environ.get("DUES").strip()) and not self.club_banned) + return self.admin_level > 1 or self.club_allowed or (self.truecoins > int(environ.get("DUES").strip()) and not self.club_banned) def any_block_exists(self, other): @@ -212,12 +215,12 @@ class User(Base): @cache.memoize(timeout=86400) def userpagelisting(self, v=None, page=1, sort="new", t="all"): - if self.shadowbanned and not (v and (v.admin_level >= 3 or v.id == self.id)): + if self.shadowbanned and not (v and (v.admin_level > 1 or v.id == self.id)): return [] posts = g.db.query(Submission.id).filter_by(author_id=self.id, is_pinned=False) - if not (v and (v.admin_level >= 3 or v.id == self.id)): + if not (v and (v.admin_level > 1 or v.id == self.id)): posts = posts.filter_by(deleted_utc=0, is_banned=False, private=False) now = int(time.time()) @@ -356,7 +359,7 @@ class User(Base): @property @lazy def post_notifications_count(self): - return g.db.query(Notification.id).join(Comment).filter(Notification.user_id == self.id, Notification.read == False, Comment.author_id == AUTOJANNY_ACCOUNT).count() + return g.db.query(Notification.id).join(Comment).filter(Notification.user_id == self.id, Notification.read == False, Comment.author_id == AUTOJANNY_ID).count() @property @@ -400,13 +403,13 @@ class User(Base): @lazy def banner_url(self): if self.bannerurl: return self.bannerurl - else: return f"http://{site}/assets/images/{site_name}/preview.webp" + else: return f"http://{site}/assets/images/{site_name}/preview.webp?v=2" @property @lazy def profile_url(self): if self.profileurl: return self.profileurl - elif "rama" in site: return f"http://{site}/assets/images/defaultpictures/{random.randint(1, 150)}.webp" + elif "rama" in site: return f"http://{site}/assets/images/defaultpictures/{random.randint(1, 150)}.webp?v=1" else: return f"http://{site}/assets/images/default-profile-pic.webp" @property @@ -464,7 +467,7 @@ class User(Base): self.profileurl = None if self.discord_id: remove_user(self) - self.is_banned = admin.id if admin else AUTOJANNY_ACCOUNT + self.is_banned = admin.id if admin else AUTOJANNY_ID if reason: self.ban_reason = reason g.db.add(self) diff --git a/files/helpers/alerts.py b/files/helpers/alerts.py index ef1335d9ab..19e70350a3 100644 --- a/files/helpers/alerts.py +++ b/files/helpers/alerts.py @@ -14,8 +14,8 @@ def send_notification(uid, text, autojanny=False): text_html = sanitize(text_html) - if autojanny: author_id = AUTOJANNY_ACCOUNT - else: author_id = NOTIFICATIONS_ACCOUNT + if autojanny: author_id = AUTOJANNY_ID + else: author_id = NOTIFICATIONS_ID new_comment = Comment(author_id=author_id, parent_submission=None, @@ -38,7 +38,7 @@ def send_follow_notif(vid, user, text): text_html = CustomRenderer().render(mistletoe.Document(text)) text_html = sanitize(text_html) - new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT, + new_comment = Comment(author_id=NOTIFICATIONS_ID, parent_submission=None, distinguish_level=6, body=text, @@ -57,7 +57,7 @@ def send_unfollow_notif(vid, user, text): text_html = CustomRenderer().render(mistletoe.Document(text)) text_html = sanitize(text_html) - new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT, + new_comment = Comment(author_id=NOTIFICATIONS_ID, parent_submission=None, distinguish_level=6, body=text, @@ -76,7 +76,7 @@ def send_block_notif(vid, user, text): text_html = CustomRenderer().render(mistletoe.Document(text)) text_html = sanitize(text_html) - new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT, + new_comment = Comment(author_id=NOTIFICATIONS_ID, parent_submission=None, distinguish_level=6, body=text, @@ -95,7 +95,7 @@ def send_unblock_notif(vid, user, text): text_html = CustomRenderer().render(mistletoe.Document(text)) text_html = sanitize(text_html) - new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT, + new_comment = Comment(author_id=NOTIFICATIONS_ID, parent_submission=None, distinguish_level=6, body=text, diff --git a/files/helpers/const.py b/files/helpers/const.py index e249e1cde3..63447a4f58 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -8,6 +8,8 @@ SLURS = { "retarded": "r-slurred", "retard": "r-slur", "tard": "r-slur", + "newfag": "newstrag", + "oldfag": "oldstrag", "faggot": "cute twink", "faggot": "cute twink", "fag": "cute twink", @@ -93,45 +95,56 @@ Thank you.""" WELCOME_MSG = "Hi there! It's me, your soon-to-be favorite rDrama user @carpathianflorist here to give you a brief rundown on some of the sick features we have here. You'll probably want to start by following me, though. So go ahead and click my name and then smash that Follow button. This is actually really important, so go on. Hurry.\n\nThanks!\n\nNext up: If you're a member of the media, similarly just shoot me a DM and I'll set about verifying you and then we can take care of your sad journalism stuff.\n\n**FOR EVERYONE ELSE**\n\n Begin by navigating to [the settings page](https://rdrama.net/settings/profile) (we'll be prettying this up so it's less convoluted soon, don't worry) and getting some basic customization done.\n\n### Themes\n\nDefinitely change your theme right away, the default one (Midnight) is pretty enough, but why not use something *exotic* like Win98, or *flashy* like Tron? Even Coffee is super tasteful and way more fun than the default. More themes to come when we get around to it!\n\n### Avatar/pfp\n\nYou'll want to set this pretty soon; without uploading one, I put together a randomly-assigned selection of 180ish pictures of furries, ugly goths, mujahideen, anime girls, and My Little Ponys which are used by everyone who was too lazy to set a pfp. Set the banner too while you're at it. Your profile is important!\n\n### Flairs\n\nSince you're already on the settings page, you may as well set a flair, too. As with your username, you can - obviously - choose the color of this, either with a hex value or just from the preset colors. And also like your username, you can change this at any time. [Paypigs](https://marsey1.gumroad.com/l/tfcvri) can even further relive the glory days of 90s-00s internet and set obnoxious signatures.\n\n### PROFILE ANTHEMS\n\nSpeaking of profiles, hey, remember MySpace? Do you miss autoplaying music assaulting your ears every time you visited a friend's page? Yeah, we brought that back. Enter a YouTube URL, wait a few seconds for it to process, and then BAM! you've got a profile anthem which people cannot mute. Unless they spend 20,000 dramacoin in the shop for a mute button. Which you can then remove from your profile by spending 40,000 dramacoin on an unmuteable anthem. Get fucked poors!\n\n### Dramacoin?\n\nDramacoin is basically our take on the karma system. Except unlike the karma system, it's not gay and boring and stupid and useless. Dramacoin can be spent at [Marsey's Dramacoin Emporium](https://rdrama.net/shop) on upgrades to your user experience (many more coming than what's already listed there), and best of all on tremendously annoying awards to fuck with your fellow dramautists. We're always adding more, so check back regularly in case you happen to miss one of the announcement posts. Holiday-themed awards are currently unavailable while we resolve an internal dispute, but they **will** return, no matter what some other janitors insist.\n\nLike karma, dramacoin is obtained by getting upvotes on your threads and comments. *Unlike* karma, it's also obtained by getting downvotes on your threads and comments. Downvotes don't really do anything here - they pay the same amount of dramacoin and they increase thread/comment ranking just the same as an upvote. You just use them to express petty disapproval and hopefully start a fight. Because all votes are visible here. To hell with your anonymity.\n\nDramacoin can also be traded amongst users from their profiles. Note that there is a 1.5% transaction fee.\n\n**Dramacoin and shop items cannot be purchased with real money and this will not change.** Though we are notoriously susceptible to bribes, so definitely shoot your shot. It'll probably go well, honestly.\n\n### Badges\n\nRemember all those neat little metallic icons you saw on my profile when you were following me? If not, scroll back up and go have a look. And doublecheck to make sure you pressed the Follow button. Anyway, those are badges. You earn them by doing a variety of things. Some of them even offer benefits, like discounts at the shop. A [complete list of badges and their requirements can be found here](https://rdrama.net/badges), though I add more pretty regularly, so keep an eye on the changelog.\n\n### Other stuff\n\nWe're always adding new features, and we take a fun-first approach to development. If you have a suggestion for something that would be fun, funny, annoying - or best of all, some combination of all three - definitely make a thread about it. Or just DM me if you're shy. Weirdo. Anyway there's also the [leaderboards](https://rdrama.net/leaderboard), boring stuff like two-factor authentication you can toggle on somewhere in the settings page (psycho), the ability to save posts and comments, close to a thousand emojis already (several hundred of which are rDrama originals), and on and on and on and on. This is just the basics, mostly to help you get acquainted with some of the things you can do here to make it more easy on the eyes, customizable, and enjoyable. If you don't enjoy it, just go away! We're not changing things to suit you! Get out of here loser! And no, you can't delete your account :na:\n\nI love you.diff --git a/files/templates/userpage.html b/files/templates/userpage.html index 35f0aed474..d4f2533a3a 100644 --- a/files/templates/userpage.html +++ b/files/templates/userpage.html @@ -5,7 +5,7 @@ {% block title %} -{% if u and u.profilecss %} +{% if u and u.profilecss and (u.admin_level or not (v and v.admin_level)) %} {% endif %} @@ -15,7 +15,7 @@ } - +{{u.username}}'s profile - {{'SITE_NAME' | app_config}} {% if u.is_private %} @@ -41,29 +41,44 @@ {% block desktopUserBanner %} - +{% endif %} + +{% if u.song %} + + +{% endif %}- {% if u.customtitle %}@@ -155,30 +170,44 @@{% if u.quadrant %}
{% endif %} + {% if u.customtitle %}{% endif %}{{u.customtitle | safe}}
{% if u.quadrant %}
+ {% else %} + {% endif %} + + +{% endif %}{{u.customtitle | safe}}
{{u.coins}} -{% if "pcm" in request.host %}+
{% if u.procoins %} {{u.procoins}} -
+
{% endif %} {% if u.stored_subscriber_count >=1 and not u.is_nofollow %}{{u.stored_subscriber_count}} follower{{'s' if u.stored_subscriber_count != 1 else ''}} {% endif %} joined {{u.created_date}}
Based Count: {{u.basedcount}}
{% endif %} + {% if u.bio_html %} - -{{u.bio_html | safe}}+ + {% if request.host == 'rdrama.net' and u.id == 2050 %} +{{u.friends_html | safe}}+ {% else %} +{{u.bio_html | safe}}+ {% endif %} {% else %} -No bio...
+No bio...
{% endif %} {% if u.friends_html %}Friends:
- {{u.friends_html | safe}} + {% if request.host == 'rdrama.net' and u.id == 2050 %} + {{u.bio_html | safe}} + {% else %} + {{u.friends_html | safe}} + {% endif %} {% endif %} {% if u.enemies_html %} @@ -208,28 +237,28 @@ Get them help Gift {{'COINS_NAME' | app_config}} - {% if 'pcm' in request.host and v.admin_level == 6 %} + {% if 'pcm' in request.host and v.admin_level > 1 %} {% if u.admin_level == 0 %} Make admin - {% elif v.id in [10,1551,1552,1577,1592] %} + {% elif v.admin_level > 2 %} Remove admin Revert admin actions {% endif %} {% endif %} - {% if 'rama' in request.host and v.id in [1,28,30,995,2513,3333] %} + {% if 'rama' in request.host and v.admin_level > 2 %} Make admin Remove admin Make fake admin Remove fake admin - {% if u.admin_level == 6 %} + {% if u.admin_level > 1 %} Revert admin actions {% endif %} {% endif %} - {% if 'rama' not in request.host and 'pcm' not in request.host and v.admin_level == 6 %} + {% if 'rama' not in request.host and 'pcm' not in request.host and v.admin_level > 1 %} Make admin Remove admin @@ -354,18 +383,20 @@ {% endif %}User ID: {{u.id}}
- {% if v and v.admin_level >=4 %} +Coins spent: {{u.coins_spent}}
+ {% if v and v.admin_level > 1 %} +True score: {{u.truecoins}}
{% if u.is_private %}User has private mode enabled.
{% endif %} + {% endif %} + {% if v and (v.admin_level > 1 or v.alt) %} Alts:
Banned by: @{{u.banned_by.username}}
@@ -431,14 +462,20 @@ {% if v and v.has_follower(u) and not v.is_nofollow %} Follows you {% endif %} - {% if u.customtitle %}{% if u.quadrant %}{% endif %}{{u.customtitle | safe}}
{% if u.quadrant %}{% endif %}{{u.customtitle | safe}}
User ID: {{u.id}}
+Coins spent: {{u.coins_spent}}
{% if v and v.admin_level > 1 %} +True score: {{u.truecoins}}
{% if u.is_private %}User has private mode enabled.
{% endif %} + {% endif %} + {% if v and (v.admin_level > 1 or v.alt) %} Alts:Banned by: @{{u.banned_by.username}}
{% endif %} -+ + ++
# | +Name | +{{name}}votes | +
---|---|---|
{{loop.index}} | +{{user[1]}} | +