From 2fa71a252b6df040f08bfb7a06199741db5642ef Mon Sep 17 00:00:00 2001 From: Aevann1 Date: Tue, 13 Sep 2022 18:53:19 +0200 Subject: [PATCH 1/5] kofi integration --- files/__main__.py | 8 ++-- files/classes/transactions.py | 2 +- files/helpers/const.py | 1 + files/helpers/jinja2.py | 2 +- files/routes/settings.py | 2 +- files/routes/users.py | 56 ++++++++++++++++++++++---- files/templates/settings_security.html | 14 ++++++- sql/20220913-transactions.sql | 2 +- 8 files changed, 70 insertions(+), 17 deletions(-) diff --git a/files/__main__.py b/files/__main__.py index 2002d9d7e..e9d54d397 100644 --- a/files/__main__.py +++ b/files/__main__.py @@ -88,9 +88,11 @@ if not path.isfile(f'/site_settings.json'): def before_request(): g.agent = request.headers.get("User-Agent") - if not g.agent: return 'Please use a "User-Agent" header!', 403 + if not g.agent and request.path != '/kofi': + return 'Please use a "User-Agent" header!', 403 - ua = g.agent.lower() + ua = g.agent or '' + ua = ua.lower() with open('/site_settings.json', 'r', encoding='utf_8') as f: app.config['SETTINGS'] = json.load(f) @@ -98,7 +100,7 @@ def before_request(): if request.host != app.config["SERVER_NAME"]: return {"error":"Unauthorized host provided."}, 401 if request.headers.get("CF-Worker"): return {"error":"Cloudflare workers are not allowed to access this website."}, 401 - if not app.config['SETTINGS']['Bots'] and request.headers.get("Authorization"): abort(503) + if not app.config['SETTINGS']['Bots'] and request.headers.get("Authorization"): abort(403) g.db = db_session() g.webview = '; wv) ' in ua diff --git a/files/classes/transactions.py b/files/classes/transactions.py index c7a162b55..6030d9897 100644 --- a/files/classes/transactions.py +++ b/files/classes/transactions.py @@ -6,7 +6,7 @@ if KOFI_TOKEN: class Transaction(Base): - __tablename__ = "kofi" + __tablename__ = "transactions" id = Column(String, primary_key=True) created_utc = Column(Integer) type = Column(String) diff --git a/files/helpers/const.py b/files/helpers/const.py index 867199d4c..89cc64e91 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -1048,6 +1048,7 @@ GIPHY_KEY = environ.get('GIPHY_KEY').strip() MASTER_KEY = environ.get("MASTER_KEY") FP = environ.get("FP") KOFI_TOKEN = environ.get("KOFI_TOKEN") +KOFI_LINK = environ.get("KOFI_LINK") tiers={ "(Paypig)": 1, diff --git a/files/helpers/jinja2.py b/files/helpers/jinja2.py index 12909d90c..719f1c6ba 100644 --- a/files/helpers/jinja2.py +++ b/files/helpers/jinja2.py @@ -58,4 +58,4 @@ def inject_constants(): "CASINO_ENABLED":CASINO_ENABLED, "GUMROAD_LINK":GUMROAD_LINK, "DEFAULT_THEME":DEFAULT_THEME, "DESCRIPTION":DESCRIPTION, "has_sidebar":has_sidebar, "has_logo":has_logo, "has_app":has_app, - "FP":FP, "NOTIF_MODACTION_JL_MIN":NOTIF_MODACTION_JL_MIN, "cache":cache, "ONLINE_STR":ONLINE_STR, "patron":patron, "approved_embed_hosts":approved_embed_hosts, "dues":dues, "SIDEBAR_THREAD":SIDEBAR_THREAD, "BANNER_THREAD":BANNER_THREAD, "BADGE_THREAD":BADGE_THREAD, "SNAPPY_THREAD":SNAPPY_THREAD} + "FP":FP, "NOTIF_MODACTION_JL_MIN":NOTIF_MODACTION_JL_MIN, "cache":cache, "ONLINE_STR":ONLINE_STR, "patron":patron, "approved_embed_hosts":approved_embed_hosts, "dues":dues, "SIDEBAR_THREAD":SIDEBAR_THREAD, "BANNER_THREAD":BANNER_THREAD, "BADGE_THREAD":BADGE_THREAD, "SNAPPY_THREAD":SNAPPY_THREAD, "KOFI_TOKEN":KOFI_TOKEN, "KOFI_LINK":KOFI_LINK} diff --git a/files/routes/settings.py b/files/routes/settings.py index a7833d9b8..f44e12070 100644 --- a/files/routes/settings.py +++ b/files/routes/settings.py @@ -343,7 +343,7 @@ def themecolor(v): @auth_required def gumroad(v): if not (v.email and v.is_activated): - return {"error": f"You must have a verified email to verify {patron} status and claim your rewards"}, 400 + return {"error": f"You must have a verified email to verify {patron} status and claim your rewards!"}, 400 data = {'access_token': GUMROAD_TOKEN, 'email': v.email} response = requests.get('https://api.gumroad.com/v2/sales', data=data, timeout=5).json()["sales"] diff --git a/files/routes/users.py b/files/routes/users.py index dfc597b28..265aa0e07 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -18,7 +18,7 @@ from collections import Counter import gevent from sys import stdout import os - +import json def leaderboard_thread(): db = db_session() @@ -1385,14 +1385,15 @@ def bid_list(v, bid): @app.post("/kofi") def kofi(): - verification_token = request.values.get('verification_token') + data = json.loads(request.values['data']) + verification_token = data['verification_token'] if verification_token != KOFI_TOKEN: abort(400) - id = request.values.get('kofi_transaction_id') - created_utc = time.mktime(time.strptime(request.values.get('timestamp'), "%Y-%m-%dT%H:%M:%SZ")) - type = request.values.get('type') - amount = int(request.values.get('amount')) - email = request.values.get('email') + id = data['kofi_transaction_id'] + created_utc = int(time.mktime(time.strptime(data['timestamp'].split('.')[0], "%Y-%m-%dT%H:%M:%S"))) + type = data['type'] + amount = int(float(data['amount'])) + email = data['email'] transaction = Transaction( id=id, @@ -1403,5 +1404,44 @@ def kofi(): ) g.db.add(transaction) + return '' - return '' \ No newline at end of file +kofi_tiers={ + 5: 1, + 10: 2, + 20: 3, + 50: 4 + } + +@app.post("/settings/kofi") +@auth_required +def settings_kofi(v): + if not (v.email and v.is_activated): + return {"error": f"You must have a verified email to verify {patron} status and claim your rewards!"}, 400 + + transaction = g.db.query(Transaction).filter_by(email=v.email).one_or_none() + + if not transaction: + return {"error": "Email not found"}, 404 + + tier = kofi_tiers[transaction.amount] + if v.patron == tier: return {"error": f"{patron} rewards already claimed"}, 400 + + procoins = procoins_li[tier] - procoins_li[v.patron] + if procoins < 0: return {"error": f"{patron} rewards already claimed"}, 400 + + existing = g.db.query(User.id).filter(User.email == v.email, User.is_activated == True, User.patron >= tier).first() + if existing: return {"error": f"{patron} rewards already claimed on another account"}, 400 + + v.patron = tier + if v.discord_id: add_role(v, f"{tier}") + + v.procoins += procoins + send_repeatable_notification(v.id, f"You have received {procoins} Marseybux! You can use them to buy awards in the [shop](/shop).") + + g.db.add(v) + + badge_grant(badge_id=20+tier, user=v) + + + return {"message": f"{patron} rewards claimed!"} \ No newline at end of file diff --git a/files/templates/settings_security.html b/files/templates/settings_security.html index f2d108543..76d4ccdb0 100644 --- a/files/templates/settings_security.html +++ b/files/templates/settings_security.html @@ -45,7 +45,11 @@ diff --git a/sql/20220913-transactions.sql b/sql/20220913-transactions.sql index 188ada617..f88768796 100644 --- a/sql/20220913-transactions.sql +++ b/sql/20220913-transactions.sql @@ -1,5 +1,5 @@ CREATE TABLE public.transactions ( - id integer PRIMARY KEY, + id character varying(36) PRIMARY KEY, created_utc integer NOT NULL, type character varying(12) NOT NULL, amount integer NOT NULL, From dff5bcefcfe828bfca602819cf7d8153d5485020 Mon Sep 17 00:00:00 2001 From: Aevann1 Date: Tue, 13 Sep 2022 19:35:33 +0200 Subject: [PATCH 2/5] add loop.index to vote tables --- files/templates/poll_votes.html | 2 ++ files/templates/votes.html | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/files/templates/poll_votes.html b/files/templates/poll_votes.html index fa1fdac84..0da37299d 100644 --- a/files/templates/poll_votes.html +++ b/files/templates/poll_votes.html @@ -18,6 +18,7 @@ + @@ -26,6 +27,7 @@ {% for vote in ups %} +
# User User Truescore Vote Time
{{loop.index}} {% with user=vote.user %} {% include "user_in_table.html" %} diff --git a/files/templates/votes.html b/files/templates/votes.html index 562a31847..37b337b07 100644 --- a/files/templates/votes.html +++ b/files/templates/votes.html @@ -30,6 +30,7 @@ + @@ -38,6 +39,7 @@ {% for vote in ups %} +
# User User Truescore Vote Time
{{loop.index}} {% with user=vote.user %} {% include "user_in_table.html" %} @@ -55,6 +57,7 @@ + @@ -63,6 +66,7 @@ {% for vote in downs %} +
# User User Truescore Vote Time
{{loop.index}} {% with user=vote.user %} {% include "user_in_table.html" %} From af66453f2bdf6e32db2233019150e35982b6c55c Mon Sep 17 00:00:00 2001 From: Aevann1 Date: Tue, 13 Sep 2022 19:45:00 +0200 Subject: [PATCH 3/5] fix NaN on gifting on mobile --- files/assets/js/userpage_v.js | 4 ++-- files/templates/util/assetcache.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/files/assets/js/userpage_v.js b/files/assets/js/userpage_v.js index dd647503b..13623ce92 100644 --- a/files/assets/js/userpage_v.js +++ b/files/assets/js/userpage_v.js @@ -31,7 +31,7 @@ function transferCoins(mobile=false) { this.disabled = true; - let amount = parseInt(document.getElementById("coin-transfer-amount").value); + let amount = parseInt(document.getElementById(mobile ? "coin-transfer-amount-mobile" : "coin-transfer-amount").value); let transferred = amount - Math.ceil(amount*TRANSFER_TAX); let username = document.getElementById('username').innerHTML; @@ -59,7 +59,7 @@ function transferBux(mobile=false) { this.disabled = true; - let amount = parseInt(document.getElementById("bux-transfer-amount").value); + let amount = parseInt(document.getElementById(mobile ? "bux-transfer-amount-mobile" : "bux-transfer-amount").value); let username = document.getElementById('username').innerHTML post_toast_callback(`/@${username}/transfer_bux`, diff --git a/files/templates/util/assetcache.html b/files/templates/util/assetcache.html index b0b31cd64..e7d208bcd 100644 --- a/files/templates/util/assetcache.html +++ b/files/templates/util/assetcache.html @@ -28,7 +28,7 @@ set CACHE_VER = { 'js/search.js': 4000, 'js/submit.js': 4000, 'js/userpage.js': 4000, - 'js/userpage_v.js': 4001, + 'js/userpage_v.js': 4002, 'js/lozad.js': 4000, 'js/sort_table.js': 4001, } From e4e42c6b2c847a61e8d2c8b88152e34518f94670 Mon Sep 17 00:00:00 2001 From: Aevann1 Date: Tue, 13 Sep 2022 20:00:11 +0200 Subject: [PATCH 4/5] give 250 DC to marsey creators --- files/routes/asset_submissions.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/files/routes/asset_submissions.py b/files/routes/asset_submissions.py index 8b9e6a5dc..035e7ddf8 100644 --- a/files/routes/asset_submissions.py +++ b/files/routes/asset_submissions.py @@ -5,6 +5,7 @@ from files.__main__ import app, limiter from files.helpers.const import * from files.helpers.actions import * from files.helpers.media import * +from files.helpers.get import * from files.helpers.wrappers import * from files.routes.static import marsey_list @@ -147,11 +148,6 @@ def approve_marsey(v, name): data=f'{{"files": ["https://{SITE}/e/{marsey.name}.webp"]}}', timeout=5) cache.delete_memoized(marsey_list) - if v.id != marsey.submitter_id: - msg = f"@{v.username} has approved a marsey you submitted: :{marsey.name}:" - send_repeatable_notification(marsey.submitter_id, msg) - - marsey.submitter_id = None move(f"/asset_submissions/marseys/{name}.webp", f"files/assets/images/emojis/{marsey.name}.webp") @@ -160,6 +156,18 @@ def approve_marsey(v, name): new_path = f'/asset_submissions/marseys/original/{name}.{i.format.lower()}' rename(highquality, new_path) + if v.id != author.id: + author.coins += 250 + g.db.add(author) + msg = f"@{v.username} has approved a marsey you made: :{marsey.name}:\nYou have receieved 250 coins as a reward!" + send_repeatable_notification(author.id, msg) + + if v.id not in (author.id, marsey.submitter_id): + msg = f"@{v.username} has approved a marsey you submitted: :{marsey.name}:" + send_repeatable_notification(marsey.submitter_id, msg) + + marsey.submitter_id = None + return {"message": f"'{marsey.name}' approved!"} From 73ae8f6e65cd3c3174b5febfe4e8c6f24c59bc3c Mon Sep 17 00:00:00 2001 From: Aevann1 Date: Tue, 13 Sep 2022 20:02:08 +0200 Subject: [PATCH 5/5] give a badge to permenantly marsified users --- files/classes/badges.py | 5 +++-- files/routes/settings.py | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/files/classes/badges.py b/files/classes/badges.py index cc94cf9e5..17e95fd65 100644 --- a/files/classes/badges.py +++ b/files/classes/badges.py @@ -51,6 +51,8 @@ class Badge(Base): @lazy def until(self): if self.badge_id == 28 and self.user.agendaposter != 1: return self.user.agendaposter + if self.badge_id == 170 and self.user.marsify != 1: return self.user.marsify + if self.badge_id == 94: return self.user.progressivestack if self.badge_id == 95: return self.user.bird if self.badge_id == 96: return self.user.flairchanged @@ -60,7 +62,6 @@ class Badge(Base): if self.badge_id == 167: return self.user.owoify if self.badge_id == 168: return self.user.bite if self.badge_id == 169: return self.user.earlylife - if self.badge_id == 170: return self.user.marsify if self.badge_id == 171: return self.user.rainbow return None @@ -70,7 +71,7 @@ class Badge(Base): def text(self): if self.until: text = self.badge.description + " until" - elif self.badge_id == 28: + elif self.badge_id in (28, 170): text = self.badge.description + " permanently" elif self.description: text = self.description diff --git a/files/routes/settings.py b/files/routes/settings.py index f44e12070..8b2b61e0d 100644 --- a/files/routes/settings.py +++ b/files/routes/settings.py @@ -103,6 +103,7 @@ def settings_profile_post(v): elif request.values.get("marsify", v.marsify) != v.marsify and v.marsify <= 1: updated = True v.marsify = int(request.values.get("marsify") == 'true') + if v.marsify: badge_grant(user=v, badge_id=170) elif request.values.get("bio") == "": v.bio = None