master
Aevann1 2021-11-21 19:40:47 +02:00
parent a66dd90553
commit 694ffb4e83
11 changed files with 234 additions and 208 deletions

View File

@ -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"<BadgeDef(badge_id={self.id})>"
@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"<Badge(user_id={self.user_id}, badge_id={self.badge_id})>"
@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

View File

@ -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(

View File

@ -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",

View File

@ -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,

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -52,12 +52,12 @@
</tr>
</thead>
<tbody>
{% for badge in badge_types %}
{% for k, v in badge_types.items() %}
<tr>
<td><input type="radio" id="badge-{{badge.id}}" name="badge_id" value="{{badge.id}}"></td>
<td><label for="badge-{{badge.id}}"><img loading="lazy" src="{{badge.path}}" width="70px" height="70px"></label></td>
<td>{{badge.name}}</td>
<td>{{badge.description}}</td>
<td><input type="radio" id="badge-{{k}}" name="badge_id" value="{{k}}"></td>
<td><label for="badge-{{k}}"><img loading="lazy" src="/assets/images/badges/{{v['name']}}.webp" width="70px" height="70px"></label></td>
<td>{{v['name']}}</td>
<td>{{v['description']}}</td>
</tr>
{% endfor %}
</table>

View File

@ -6,11 +6,10 @@
</pre>
<h1>User Badges</h1>
<div>This page describes the requirements for obtaining all profile badges.</div>
<div>Badges are sorted into bronze, silver, gold, and diamond tiers, based on the relative difficulty of obtaining them.</div>
<pre>
<h2 class="mt-3">Unlockable Badges</h2>
<div>These badges are automatically granted through different kinds of activity on {{'SITE_NAME' | app_config}}.</div>
<pre></pre>
</pre>
<table class="table table-striped mb-5">
<thead class="bg-primary text-white">
<tr>
@ -19,52 +18,11 @@
<th>Description</th>
</tr>
</thead>
{% for badge in badges if badge.kind==1 %}
{% for k,v in badges.items() %}
<tr>
<td>{{badge.name}}</td>
<td><img loading="lazy" src="{{badge.path}}" width=50 height=50>
<td>{{badge.description}}</td>
</tr>
{% endfor %}
</table>
<h2 class="mt-3">Granted Badges</h2>
<div>These badges can be granted by admins.</div>
<pre></pre>
<table class="table table-striped mb-5">
<thead class="bg-primary text-white">
<tr>
<th>Name</th>
<th>Image</th>
<th>Description</th>
</tr>
</thead>
{% for badge in badges if badge.kind==3 %}
<tr>
<td>{{badge.name}}</td>
<td><img loading="lazy" src="{{badge.path}}" width=50 height=50>
<td>{{badge.description}}</td>
</tr>
{% endfor %}
</table>
<h2 class="mt-3">Unobtainable Badges</h2>
<div>There is no way to acquire these badges if you don't already have them.</div>
<pre></pre>
<table class="table table-striped mb-5">
<thead class="bg-primary text-white">
<tr>
<th>Name</th>
<th>Image</th>
<th>Description</th>
</tr>
</thead>
{% for badge in badges if badge.kind==4 %}
<tr>
<td>{{badge.name}}</td>
<td><img loading="lazy" src="{{badge.path}}" width=50 height=50>
<td>{{badge.description}}</td>
<td>{{v['name']}}</td>
<td><img loading="lazy" src="/assets/images/badges/{{v['name']}}.webp" width=50 height=50>
<td>{{v['description']}}</td>
</tr>
{% endfor %}
</table>

View File

@ -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: -
--

View File

@ -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 (