From 694ffb4e830475daf51832b80cb2b6af5533bbb0 Mon Sep 17 00:00:00 2001 From: Aevann1 Date: Sun, 21 Nov 2021 19:40:47 +0200 Subject: [PATCH] badges --- files/classes/badges.py | 59 ++------ files/classes/user.py | 4 +- files/helpers/const.py | 191 +++++++++++++++++++++++++ files/routes/admin.py | 4 +- files/routes/login.py | 26 ++-- files/routes/search.py | 2 +- files/routes/static.py | 6 +- files/templates/admin/badge_grant.html | 10 +- files/templates/badges.html | 56 +------- schema.sql | 58 -------- seed-db.sql | 26 ---- 11 files changed, 234 insertions(+), 208 deletions(-) diff --git a/files/classes/badges.py b/files/classes/badges.py index 3bbf7834c..45ed2d922 100644 --- a/files/classes/badges.py +++ b/files/classes/badges.py @@ -3,42 +3,11 @@ from sqlalchemy.orm import relationship from files.__main__ import Base, app from os import environ from files.helpers.lazy import lazy +from files.helpers.const import BADGES from datetime import datetime site_name = environ.get("SITE_NAME").strip() -class BadgeDef(Base): - - __tablename__ = "badge_defs" - - id = Column(BigInteger, primary_key=True) - name = Column(String) - description = Column(String) - icon = Column(String) - kind = Column(Integer, default=1) - qualification_expr = Column(String) - - def __repr__(self): - - return f"" - - @property - @lazy - def path(self): - - return f"/assets/images/badges/{self.icon}.webp" - - @property - @lazy - def json_core(self): - return { - "name": self.name, - "description": self.description, - "icon": self.icon - } - - - class Badge(Base): __tablename__ = "badges" @@ -46,41 +15,37 @@ class Badge(Base): id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey('users.id')) - badge_id = Column(Integer, ForeignKey("badge_defs.id")) + badge_id = Column(Integer) description = Column(String) url = Column(String) - badge = relationship("BadgeDef", viewonly=True) - user = relationship("User", viewonly=True) - def __repr__(self): - return f"" + @property + @lazy + def badge(self): + return BADGES[self.badge_id] + @property @lazy def text(self): if self.name == "Agendaposter": ti = self.user.agendaposter_expires_utc - if ti: return self.badge.description + " until " + datetime.utcfromtimestamp(ti).strftime('%Y-%m-%d %H:%M:%S') - else: return self.badge.description + " permanently" + if ti: return self.badge['description'] + " until " + datetime.utcfromtimestamp(ti).strftime('%Y-%m-%d %H:%M:%S') + else: return self.badge['description'] + " permanently" elif self.description: return self.description - else: return self.badge.description - - @property - @lazy - def type(self): - return self.badge.id + else: return self.badge['description'] @property @lazy def name(self): - return self.badge.name + return self.badge['name'] @property @lazy def path(self): - return self.badge.path + return f"/assets/images/badges/{self.name}.webp" @property @lazy diff --git a/files/classes/user.py b/files/classes/user.py index d7dc71a0f..858821356 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -272,8 +272,8 @@ class User(Base): if not self.is_suspended: return None return g.db.query(User).filter_by(id=self.is_banned).first() - def has_badge(self, badgedef_id): - return g.db.query(Badge).filter_by(user_id=self.id, badge_id=badgedef_id).first() + def has_badge(self, badge_id): + return g.db.query(Badge).filter_by(user_id=self.id, badge_id=badge_id).first() def hash_password(self, password): return generate_password_hash( diff --git a/files/helpers/const.py b/files/helpers/const.py index 34dbfa916..86b3cf5dc 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -163,6 +163,197 @@ def censor_slurs(body: str, logged_user) -> str: if not logged_user or logged_user.slurreplacer: body = SLUR_REGEX.sub(sub_matcher, body) return body +BADGES = { + 1: { + 'name': 'Alpha User', + 'description': 'Joined during open alpha' + }, + 2: { + 'name': 'Verified Email', + 'description': 'Verified Email' + }, + 3: { + 'name': 'Code Contributor', + 'description': 'Contributed to Drama source code' + }, + 4: { + 'name': 'White Hat', + 'description': 'Responsibly reported a security issue' + }, + 6: { + 'name': 'Beta User', + 'description': 'Joined during open beta' + }, + 7: { + 'name': 'Bug Finder', + 'description': 'Found a bug' + }, + 10: { + 'name': 'Bronze Recruiter', + 'description': 'Recruited 1 friend to join Drama' + }, + 11: { + 'name': 'Silver Recruiter', + 'description': 'Recruited 10 friends to join Drama' + }, + 12: { + 'name': 'Gold Recruiter', + 'description': 'Recruited 100 friends to join Drama' + }, + 15: { + 'name': 'Idea Maker', + 'description': 'Had a good idea for Drama which was implemented by the developers' + }, + 16: { + 'name': 'Marsey Master', + 'description': 'Contributed 10 (or more!!!!) Marsey emojis ✨' + }, + 17: { + 'name': 'Marsey Artisan', + 'description': 'Contributed a Marsey emoji ✨' + }, + 18: { + 'name': 'Artisan', + 'description': 'Contributed to Drama artwork' + }, + 21: { + 'name': 'Paypig', + 'description': 'Contributed at least $5/month' + }, + 22: { + 'name': 'Renthog', + 'description': 'Contributed at least $10/month' + }, + 23: { + 'name': 'Landchad', + 'description': 'Contributed at least $20/month' + }, + 24: { + 'name': 'Terminally online turboautist', + 'description': 'Contributed at least $50/month' + }, + 25: { + 'name': 'Footpig', + 'description': 'Contributed at least $100/month' + }, + 26: { + 'name': 'Agendaposter', + 'description': 'Forced to use the agendaposter theme' + }, + 27: { + 'name': 'Lolcow', + 'description': 'Beautiful and valid milk provider' + }, + 28: { + 'name': 'Rich Bich', + 'description': 'Contributed $500' + }, + 58: { + 'name': 'Diamond Recruiter', + 'description': 'Recruited 1000 friends to join Drama' + }, + 60: { + 'name': 'Unironically Retarded', + 'description': 'Demonstrated a wholesale inability to read the room' + }, + 61: { + 'name': 'Lab Rat', + 'description': 'Helped test features in development' + }, + 62: { + 'name': 'Master Baiter', + 'description': 'For outstanding achievement in the field of catching fish' + }, + 63: { + 'name': 'Balls', + 'description': 'I wrote carp on my balls as a sign of submission' + }, + 64: { + 'name': 'The Other Kind Of Good Journalist', + 'description': 'Contributed positive media attention to rDrama' + }, + 65: { + 'name': '2021 Spooooooky Marsey Artist', + 'description': 'Contributed a VERY SCARY Marsey for Halloween 2021!' + }, + 66: { + 'name': 'Sk8r Boi', + 'description': 'Certifies that this user is NOT a poser' + }, + 67: { + 'name': 'Unpausable', + 'description': 'Spent 40,000 dramacoins on an unpausable profile anthem' + }, + 68: { + 'name': 'Pause Button', + 'description': 'Spent 20,000 dramacoins on a profile anthem pause button' + }, + 69: { + 'name': 'Little Big Spender', + 'description': 'Dropped 10,000 dramacoins at the shop' + }, + 70: { + 'name': 'Big Spender', + 'description': 'Dropped 100,000 dramacoins at the shop' + }, + 71: { + 'name': 'Big Big Spender', + 'description': 'Dropped 250,000 dramacoins at the shop' + }, + 72: { + 'name': 'Big Big Big Spender', + 'description': 'Dropped 500,000 dramacoins at the shop' + }, + 73: { + 'name': 'Le Rich Gentlesir', + 'description': 'Spent a fucking million dramacoins at the shop' + }, + 74: { + 'name': 'Grass Toucher', + 'description': 'Awarded for molesting plant life' + }, + 75: { + 'name': 'Halloween 21', + 'description': 'Awarded for surviving Homoween 2021' + }, + 76: { + 'name': 'Low Roller', + 'description': 'Bought 10 lootboxes' + }, + 77: { + 'name': 'Middle Roller', + 'description': 'Bought 50 lootboxes' + }, + 78: { + 'name': 'High Roller', + 'description': 'Bought 150 lootboxes' + }, + 79: { + 'name': 'Merchant', + 'description': "Contributed a new line of product to Marsey's Coin Emporium" + }, + 80: { + 'name': 'Artist Laureate', + 'description': '' + }, + 81: { + 'name': 'Patron of the Arts', + 'description': 'Sponsored the creation of an approved Marsey' + }, + 82: { + 'name': 'Background', + 'description': 'Bought a profile background from the shop' + }, + 83: { + 'name': 'All-Seeing Eye', + 'description': 'Can view private profiles' + }, + 84: { + 'name': 'Alt-Seeing Eye', + 'description': 'Can see alts' + } +} + AWARDS = { "shit": { "kind": "shit", diff --git a/files/routes/admin.py b/files/routes/admin.py index 47caf4368..2ee33ef7f 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -351,15 +351,13 @@ def disablesignups(v): @admin_level_required(2) def badge_grant_get(v): - badge_types = g.db.query(BadgeDef).all() - errors = {"already_owned": "That user already has that badge.", "no_user": "That user doesn't exist." } return render_template("admin/badge_grant.html", v=v, - badge_types=badge_types, + badge_types=BADGES, error=errors.get( request.values.get("error"), None) if request.values.get('error') else None, diff --git a/files/routes/login.py b/files/routes/login.py index 09de77f32..983620149 100644 --- a/files/routes/login.py +++ b/files/routes/login.py @@ -301,21 +301,21 @@ def sign_up_post(v): ref_id = int(request.values.get("referred_by", 0)) - if ref_id: - ref_user = g.db.query(User).filter_by(id=ref_id).first() + # if ref_id: + # ref_user = g.db.query(User).filter_by(id=ref_id).first() - if ref_user: - badge_types = g.db.query(BadgeDef).filter(BadgeDef.qualification_expr.isnot(None)).all() - for badge in badge_types: - if eval(badge.qualification_expr, {}, {'v': ref_user}): - if not ref_user.has_badge(badge.id): - new_badge = Badge(user_id=ref_user.id, badge_id=badge.id) - g.db.add(new_badge) - else: - bad_badge = ref_user.has_badge(badge.id) - if bad_badge: g.db.delete(bad_badge) + # if ref_user: + # badge_types = g.db.query(BadgeDef).filter(BadgeDef.qualification_expr.isnot(None)).all() + # for badge in badge_types: + # if eval(badge.qualification_expr, {}, {'v': ref_user}): + # if not ref_user.has_badge(badge.id): + # new_badge = Badge(user_id=ref_user.id, badge_id=badge.id) + # g.db.add(new_badge) + # else: + # bad_badge = ref_user.has_badge(badge.id) + # if bad_badge: g.db.delete(bad_badge) - g.db.add(ref_user) + # g.db.add(ref_user) id_1 = g.db.query(User.id).filter_by(id=7).count() users_count = g.db.query(User.id).count() diff --git a/files/routes/search.py b/files/routes/search.py index 9608b12e4..76e6c992e 100644 --- a/files/routes/search.py +++ b/files/routes/search.py @@ -93,7 +93,7 @@ def searchposts(v): ) if not (v and v.admin_level > 1): - posts.filter(Submission.deleted_utc == 0, Submission.is_banned == False) + posts = posts.filter(Submission.deleted_utc == 0, Submission.is_banned == False) if not (v and v.eye): posts = posts.join(User, User.id==Submission.author_id).filter(User.is_private == False) if v and v.admin_level > 1: pass diff --git a/files/routes/static.py b/files/routes/static.py index 0073bd398..208330900 100644 --- a/files/routes/static.py +++ b/files/routes/static.py @@ -1,6 +1,7 @@ from files.mail import * from files.__main__ import app, limiter, mail from files.helpers.alerts import * +from files.helpers.const import BADGES from files.classes.award import AWARDS from sqlalchemy import func from os import path @@ -294,10 +295,7 @@ def settings_profile(v): @app.get("/badges") @auth_desired def badges(v): - - - badges = g.db.query(BadgeDef).all() - return render_template("badges.html", v=v, badges=badges) + return render_template("badges.html", v=v, badges=BADGES) @app.get("/blocks") @auth_desired diff --git a/files/templates/admin/badge_grant.html b/files/templates/admin/badge_grant.html index 185a283dc..11c7c0462 100644 --- a/files/templates/admin/badge_grant.html +++ b/files/templates/admin/badge_grant.html @@ -52,12 +52,12 @@ -{% for badge in badge_types %} +{% for k, v in badge_types.items() %} - - - {{badge.name}} - {{badge.description}} + + + {{v['name']}} + {{v['description']}} {% endfor %} diff --git a/files/templates/badges.html b/files/templates/badges.html index 3ca6289db..9e04e8240 100644 --- a/files/templates/badges.html +++ b/files/templates/badges.html @@ -6,11 +6,10 @@

User Badges

This page describes the requirements for obtaining all profile badges.
-
Badges are sorted into bronze, silver, gold, and diamond tiers, based on the relative difficulty of obtaining them.
+
 
-

Unlockable Badges

-
These badges are automatically granted through different kinds of activity on {{'SITE_NAME' | app_config}}.
-

+
+
@@ -19,52 +18,11 @@ -{% for badge in badges if badge.kind==1 %} +{% for k,v in badges.items() %} - - - -{% endfor %} -
Description
{{badge.name}} - {{badge.description}}
- - -

Granted Badges

-
These badges can be granted by admins.
-

-
-
-	
-		
-		
-		
-	
-
-{% for badge in badges if badge.kind==3 %}
-	
-		
-		
-	
-{% endfor %}
-
NameImageDescription
{{badge.name}} - {{badge.description}}
- -

Unobtainable Badges

-
There is no way to acquire these badges if you don't already have them.
-

-
-
-	
-		
-		
-		
-	
-
-{% for badge in badges if badge.kind==4 %}
-	
-		
-		
+		
+		
 {% endfor %}
 
NameImageDescription
{{badge.name}} - {{badge.description}}{{v['name']}} + {{v['description']}}
diff --git a/schema.sql b/schema.sql index d01ed54a8..8658f769a 100644 --- a/schema.sql +++ b/schema.sql @@ -127,20 +127,6 @@ CREATE SEQUENCE public.award_relationships_id_seq ALTER SEQUENCE public.award_relationships_id_seq OWNED BY public.award_relationships.id; --- --- Name: badge_defs; Type: TABLE; Schema: public; Owner: - --- - -CREATE TABLE public.badge_defs ( - id integer NOT NULL, - name character varying(64), - description character varying(256), - icon character varying(64), - kind integer, - qualification_expr character varying(128) -); - - -- -- Name: badge_list_id_seq; Type: SEQUENCE; Schema: public; Owner: - -- @@ -154,13 +140,6 @@ CREATE SEQUENCE public.badge_list_id_seq CACHE 1; --- --- Name: badge_list_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: - --- - -ALTER SEQUENCE public.badge_list_id_seq OWNED BY public.badge_defs.id; - - -- -- Name: badges; Type: TABLE; Schema: public; Owner: - -- @@ -899,12 +878,6 @@ ALTER TABLE ONLY public.alts ALTER COLUMN id SET DEFAULT nextval('public.alts_id ALTER TABLE ONLY public.award_relationships ALTER COLUMN id SET DEFAULT nextval('public.award_relationships_id_seq'::regclass); --- --- Name: badge_defs id; Type: DEFAULT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.badge_defs ALTER COLUMN id SET DEFAULT nextval('public.badge_list_id_seq'::regclass); - -- -- Name: badges id; Type: DEFAULT; Schema: public; Owner: - @@ -1056,22 +1029,6 @@ ALTER TABLE ONLY public.award_relationships ADD CONSTRAINT award_relationships_pkey PRIMARY KEY (id); --- --- Name: badge_defs badge_defs_pkey; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.badge_defs - ADD CONSTRAINT badge_defs_pkey PRIMARY KEY (id); - - --- --- Name: badge_defs badge_list_icon_key; Type: CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.badge_defs - ADD CONSTRAINT badge_list_icon_key UNIQUE (icon); - - -- -- Name: badges badges_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -1363,13 +1320,6 @@ CREATE INDEX award_post_idx ON public.award_relationships USING btree (submissio CREATE INDEX award_user_idx ON public.award_relationships USING btree (user_id); --- --- Name: badgedef_qual_idx; Type: INDEX; Schema: public; Owner: - --- - -CREATE INDEX badgedef_qual_idx ON public.badge_defs USING btree (qualification_expr); - - -- -- Name: badges_badge_id_idx; Type: INDEX; Schema: public; Owner: - -- @@ -1755,14 +1705,6 @@ CREATE INDEX votes_submission_id_index ON public.votes USING btree (submission_i CREATE INDEX votes_type_index ON public.votes USING btree (vote_type); --- --- Name: badges badges_badge_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public.badges - ADD CONSTRAINT badges_badge_id_fkey FOREIGN KEY (badge_id) REFERENCES public.badge_defs(id); - - -- -- Name: commentflags commentflags_comment_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - -- diff --git a/seed-db.sql b/seed-db.sql index 6ffa55ae2..2e5252333 100644 --- a/seed-db.sql +++ b/seed-db.sql @@ -1,29 +1,3 @@ -INSERT INTO public.badge_defs VALUES (12, 'Gold Recruiter', 'Recruited 100 friends to join Drama', 'recruit-100', 'v.referral_count>=100 and v.referral_count <=999'); -INSERT INTO public.badge_defs VALUES (11, 'Silver Recruiter', 'Recruited 10 friends to join Drama', 'recruit-10', 'v.referral_count>=10 and v.referral_count <= 99'); -INSERT INTO public.badge_defs VALUES (10, 'Bronze Recruiter', 'Recruited 1 friend to join Drama', 'recruit-1', 'v.referral_count>=1 and v.referral_count<9'); -INSERT INTO public.badge_defs VALUES (58, 'Diamond Recruiter', 'Recruited 1000 friends to join Drama', 'recruit-1000', 'v.referral_count >= 1000'); -INSERT INTO public.badge_defs VALUES (25, 'Footpig', 'Contributed at least $100/month', 'patron-5', 3, NULL); -INSERT INTO public.badge_defs VALUES (61, 'Lab Rat', 'Helped test features in development', 'labrat', 3, NULL); -INSERT INTO public.badge_defs VALUES (63, 'Balls', 'I wrote carp on my balls as a sign of submission', 'carpballs', 3, NULL); -INSERT INTO public.badge_defs VALUES (4, 'White Hat', 'Responsibly reported a security issue', 'whitehat', 3, NULL); -INSERT INTO public.badge_defs VALUES (2, 'Verified Email', 'Verified Email', 'mail', NULL); -INSERT INTO public.badge_defs VALUES (6, 'Beta User', 'Joined during open beta', 'beta', 4, NULL); -INSERT INTO public.badge_defs VALUES (15, 'Idea Maker', 'Had a good idea for Drama which was implemented by the developers', 'idea', 3, NULL); -INSERT INTO public.badge_defs VALUES (3, 'Code Contributor', 'Contributed to Drama source code', 'git', 3, NULL); -INSERT INTO public.badge_defs VALUES (1, 'Alpha User', 'Joined during open alpha', 'alpha', 4, NULL); -INSERT INTO public.badge_defs VALUES (18, 'Artisan', 'Contributed to Drama artwork', 'art', 3, NULL); -INSERT INTO public.badge_defs VALUES (27, 'Lolcow', 'Beautiful and valid milk provider', 'lolcow', 3, NULL); -INSERT INTO public.badge_defs VALUES (21, 'Paypig', 'Contributed at least $5/month', 'patron-1', 3, NULL); -INSERT INTO public.badge_defs VALUES (22, 'Renthog', 'Contributed at least $10/month', 'patron-2', 3, NULL); -INSERT INTO public.badge_defs VALUES (23, 'Landchad', 'Contributed at least $20/month', 'patron-3', 3, NULL); -INSERT INTO public.badge_defs VALUES (24, 'Terminally online turboautist', 'Contributed at least $50/month', 'patron-4', 3, NULL); -INSERT INTO public.badge_defs VALUES (28, 'Rich Bich', 'Contributed $500', 'patron-8', 3, NULL); -INSERT INTO public.badge_defs VALUES (7, 'Bug Finder', 'Found a bug', 'sitebreaker', 3, NULL); -INSERT INTO public.badge_defs VALUES (60, 'Unironically Retarded', 'Demonstrated a wholesale inability to read the room', 'retarded', 3, NULL); -INSERT INTO public.badge_defs VALUES (26, 'Agendaposter', 'Forced to use the agendaposter theme', 'agendaposter', NULL); -INSERT INTO public.badge_defs VALUES (17, 'Marsey Artisan', 'Contributed a Marsey emoji ✨', 'marseybadge-1', 3, NULL); -INSERT INTO public.badge_defs VALUES (16, 'Marsey Master', 'Contributed 10 (or more!!!!) Marsey emojis ✨', 'marseybadge-2', 3, NULL); - insert into public.award_relationships(id,user_id,kind) values(1,1,'shit'); INSERT INTO public.users (