mirror of
https://github.com/TitanEmbeds/Titan.git
synced 2024-12-25 06:27:03 +01:00
Paypal (#41)
* Implement Titan Tokens clientside * Titan Tokens can be modified in the admin panel
This commit is contained in:
parent
d363b66799
commit
8bc95f7b0e
160
webapp/alembic/versions/2a2f32ac91d6_added_titan_tokens.py
Normal file
160
webapp/alembic/versions/2a2f32ac91d6_added_titan_tokens.py
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
"""Added Titan Tokens
|
||||||
|
|
||||||
|
Revision ID: 2a2f32ac91d6
|
||||||
|
Revises: 6fe130518448
|
||||||
|
Create Date: 2017-08-13 22:44:15.996936
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '2a2f32ac91d6'
|
||||||
|
down_revision = '6fe130518448'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import mysql
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table('titan_tokens',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('user_id', sa.String(length=255), nullable=False),
|
||||||
|
sa.Column('tokens', sa.Integer(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_table('token_transactions',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('user_id', sa.String(length=255), nullable=False),
|
||||||
|
sa.Column('timestamp', sa.TIMESTAMP(), nullable=False),
|
||||||
|
sa.Column('action', sa.String(length=255), nullable=False),
|
||||||
|
sa.Column('net_tokens', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('start_tokens', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('end_tokens', sa.Integer(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.alter_column(u'cosmetics', 'css',
|
||||||
|
existing_type=mysql.TINYINT(display_width=1),
|
||||||
|
type_=sa.Boolean(),
|
||||||
|
existing_nullable=False)
|
||||||
|
op.alter_column(u'guild_members', 'active',
|
||||||
|
existing_type=mysql.TINYINT(display_width=1),
|
||||||
|
type_=sa.Boolean(),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text(u"'1'"))
|
||||||
|
op.alter_column(u'guild_members', 'banned',
|
||||||
|
existing_type=mysql.TINYINT(display_width=1),
|
||||||
|
type_=sa.Boolean(),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text(u"'0'"))
|
||||||
|
op.alter_column(u'guilds', 'bracket_links',
|
||||||
|
existing_type=mysql.TINYINT(display_width=1),
|
||||||
|
type_=sa.Boolean(),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text(u"'1'"))
|
||||||
|
op.alter_column(u'guilds', 'channels',
|
||||||
|
existing_type=mysql.LONGTEXT(collation=u'utf8mb4_unicode_ci'),
|
||||||
|
type_=sa.Text(length=4294967295),
|
||||||
|
existing_nullable=False)
|
||||||
|
op.alter_column(u'guilds', 'chat_links',
|
||||||
|
existing_type=mysql.TINYINT(display_width=1),
|
||||||
|
type_=sa.Boolean(),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text(u"'1'"))
|
||||||
|
op.alter_column(u'guilds', 'emojis',
|
||||||
|
existing_type=mysql.LONGTEXT(collation=u'utf8mb4_unicode_ci'),
|
||||||
|
type_=sa.Text(length=4294967295),
|
||||||
|
existing_nullable=False)
|
||||||
|
op.alter_column(u'guilds', 'roles',
|
||||||
|
existing_type=mysql.LONGTEXT(collation=u'utf8mb4_unicode_ci'),
|
||||||
|
type_=sa.Text(length=4294967295),
|
||||||
|
existing_nullable=False)
|
||||||
|
op.alter_column(u'guilds', 'unauth_users',
|
||||||
|
existing_type=mysql.TINYINT(display_width=1),
|
||||||
|
type_=sa.Boolean(),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text(u"'1'"))
|
||||||
|
op.alter_column(u'guilds', 'visitor_view',
|
||||||
|
existing_type=mysql.TINYINT(display_width=1),
|
||||||
|
type_=sa.Boolean(),
|
||||||
|
existing_nullable=False)
|
||||||
|
op.alter_column(u'guilds', 'webhooks',
|
||||||
|
existing_type=mysql.LONGTEXT(collation=u'utf8mb4_unicode_ci'),
|
||||||
|
type_=sa.Text(length=4294967295),
|
||||||
|
existing_nullable=False)
|
||||||
|
op.alter_column(u'unauthenticated_users', 'revoked',
|
||||||
|
existing_type=mysql.TINYINT(display_width=1),
|
||||||
|
type_=sa.Boolean(),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text(u"'0'"))
|
||||||
|
op.alter_column(u'user_css', 'css',
|
||||||
|
existing_type=mysql.LONGTEXT(collation=u'utf8mb4_unicode_ci'),
|
||||||
|
type_=sa.Text(length=4294967295),
|
||||||
|
existing_nullable=True)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.alter_column(u'user_css', 'css',
|
||||||
|
existing_type=sa.Text(length=4294967295),
|
||||||
|
type_=mysql.LONGTEXT(collation=u'utf8mb4_unicode_ci'),
|
||||||
|
existing_nullable=True)
|
||||||
|
op.alter_column(u'unauthenticated_users', 'revoked',
|
||||||
|
existing_type=sa.Boolean(),
|
||||||
|
type_=mysql.TINYINT(display_width=1),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text(u"'0'"))
|
||||||
|
op.alter_column(u'guilds', 'webhooks',
|
||||||
|
existing_type=sa.Text(length=4294967295),
|
||||||
|
type_=mysql.LONGTEXT(collation=u'utf8mb4_unicode_ci'),
|
||||||
|
existing_nullable=False)
|
||||||
|
op.alter_column(u'guilds', 'visitor_view',
|
||||||
|
existing_type=sa.Boolean(),
|
||||||
|
type_=mysql.TINYINT(display_width=1),
|
||||||
|
existing_nullable=False)
|
||||||
|
op.alter_column(u'guilds', 'unauth_users',
|
||||||
|
existing_type=sa.Boolean(),
|
||||||
|
type_=mysql.TINYINT(display_width=1),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text(u"'1'"))
|
||||||
|
op.alter_column(u'guilds', 'roles',
|
||||||
|
existing_type=sa.Text(length=4294967295),
|
||||||
|
type_=mysql.LONGTEXT(collation=u'utf8mb4_unicode_ci'),
|
||||||
|
existing_nullable=False)
|
||||||
|
op.alter_column(u'guilds', 'emojis',
|
||||||
|
existing_type=sa.Text(length=4294967295),
|
||||||
|
type_=mysql.LONGTEXT(collation=u'utf8mb4_unicode_ci'),
|
||||||
|
existing_nullable=False)
|
||||||
|
op.alter_column(u'guilds', 'chat_links',
|
||||||
|
existing_type=sa.Boolean(),
|
||||||
|
type_=mysql.TINYINT(display_width=1),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text(u"'1'"))
|
||||||
|
op.alter_column(u'guilds', 'channels',
|
||||||
|
existing_type=sa.Text(length=4294967295),
|
||||||
|
type_=mysql.LONGTEXT(collation=u'utf8mb4_unicode_ci'),
|
||||||
|
existing_nullable=False)
|
||||||
|
op.alter_column(u'guilds', 'bracket_links',
|
||||||
|
existing_type=sa.Boolean(),
|
||||||
|
type_=mysql.TINYINT(display_width=1),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text(u"'1'"))
|
||||||
|
op.alter_column(u'guild_members', 'banned',
|
||||||
|
existing_type=sa.Boolean(),
|
||||||
|
type_=mysql.TINYINT(display_width=1),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text(u"'0'"))
|
||||||
|
op.alter_column(u'guild_members', 'active',
|
||||||
|
existing_type=sa.Boolean(),
|
||||||
|
type_=mysql.TINYINT(display_width=1),
|
||||||
|
existing_nullable=False,
|
||||||
|
existing_server_default=sa.text(u"'1'"))
|
||||||
|
op.alter_column(u'cosmetics', 'css',
|
||||||
|
existing_type=sa.Boolean(),
|
||||||
|
type_=mysql.TINYINT(display_width=1),
|
||||||
|
existing_nullable=False)
|
||||||
|
op.drop_table('token_transactions')
|
||||||
|
op.drop_table('titan_tokens')
|
||||||
|
# ### end Alembic commands ###
|
@ -5,6 +5,10 @@ config = {
|
|||||||
'client-secret': "Your discord client secret",
|
'client-secret': "Your discord client secret",
|
||||||
'bot-token': "Discord bot token",
|
'bot-token': "Discord bot token",
|
||||||
|
|
||||||
|
# Rest API in https://developer.paypal.com/developer/applications
|
||||||
|
'paypal-client-id': "Paypal client id",
|
||||||
|
'paypal-client-secret': "Paypal client secret",
|
||||||
|
|
||||||
'app-location': "/var/www/Titan/webapp/",
|
'app-location': "/var/www/Titan/webapp/",
|
||||||
'app-secret': "Type something random here, go wild.",
|
'app-secret': "Type something random here, go wild.",
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from flask import Blueprint, url_for, redirect, session, render_template, abort, request, jsonify
|
from flask import Blueprint, url_for, redirect, session, render_template, abort, request, jsonify
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from titanembeds.database import db, get_administrators_list, Cosmetics, Guilds, UnauthenticatedUsers, UnauthenticatedBans
|
from titanembeds.database import db, get_administrators_list, Cosmetics, Guilds, UnauthenticatedUsers, UnauthenticatedBans, TitanTokens, TokenTransactions, get_titan_token, set_titan_token
|
||||||
from titanembeds.oauth import generate_guild_icon_url
|
from titanembeds.oauth import generate_guild_icon_url
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
@ -172,3 +172,52 @@ def update_administrate_guild(guild_id):
|
|||||||
def guilds():
|
def guilds():
|
||||||
guilds = db.session.query(Guilds).all()
|
guilds = db.session.query(Guilds).all()
|
||||||
return render_template("admin_guilds.html.j2", servers=guilds, icon_generate=generate_guild_icon_url)
|
return render_template("admin_guilds.html.j2", servers=guilds, icon_generate=generate_guild_icon_url)
|
||||||
|
|
||||||
|
@admin.route("/tokens", methods=["GET"])
|
||||||
|
@is_admin
|
||||||
|
def manage_titan_tokens():
|
||||||
|
tokeners = db.session.query(TitanTokens).all()
|
||||||
|
donators = []
|
||||||
|
for usr in tokeners:
|
||||||
|
row = {
|
||||||
|
"user_id": usr.user_id,
|
||||||
|
"tokens": usr.tokens,
|
||||||
|
"transactions": []
|
||||||
|
}
|
||||||
|
transact = db.session.query(TokenTransactions).filter(TokenTransactions.user_id == usr.user_id).all()
|
||||||
|
for tr in transact:
|
||||||
|
row["transactions"].append({
|
||||||
|
"id": tr.id,
|
||||||
|
"user_id": tr.user_id,
|
||||||
|
"timestamp": tr.timestamp,
|
||||||
|
"action": tr.action,
|
||||||
|
"net_tokens": tr.net_tokens,
|
||||||
|
"start_tokens": tr.start_tokens,
|
||||||
|
"end_tokens": tr.end_tokens
|
||||||
|
})
|
||||||
|
donators.append(row)
|
||||||
|
return render_template("admin_token_transactions.html.j2", donators=donators)
|
||||||
|
|
||||||
|
@admin.route("/tokens", methods=["POST"])
|
||||||
|
@is_admin
|
||||||
|
def post_titan_tokens():
|
||||||
|
user_id = request.form.get("user_id", None)
|
||||||
|
amount = request.form.get("amount", None, type=int)
|
||||||
|
if not user_id or not amount:
|
||||||
|
abort(400)
|
||||||
|
if get_titan_token(user_id) != -1:
|
||||||
|
abort(409)
|
||||||
|
set_titan_token(user_id, amount, "NEW VIA ADMIN")
|
||||||
|
return ('', 204)
|
||||||
|
|
||||||
|
@admin.route("/tokens", methods=["PATCH"])
|
||||||
|
@is_admin
|
||||||
|
def patch_titan_tokens():
|
||||||
|
user_id = request.form.get("user_id", None)
|
||||||
|
amount = request.form.get("amount", None, type=int)
|
||||||
|
if not user_id or not amount:
|
||||||
|
abort(400)
|
||||||
|
if get_titan_token(user_id) == -1:
|
||||||
|
abort(409)
|
||||||
|
set_titan_token(user_id, amount, "MODIFY VIA ADMIN")
|
||||||
|
return ('', 204)
|
@ -1,10 +1,12 @@
|
|||||||
from flask import Blueprint, request, redirect, jsonify, abort, session, url_for, render_template
|
from flask import Blueprint, request, redirect, jsonify, abort, session, url_for, render_template
|
||||||
|
from flask import current_app as app
|
||||||
from config import config
|
from config import config
|
||||||
from titanembeds.decorators import discord_users_only
|
from titanembeds.decorators import discord_users_only
|
||||||
from titanembeds.database import db, Guilds, UnauthenticatedUsers, UnauthenticatedBans, Cosmetics, UserCSS
|
from titanembeds.database import db, Guilds, UnauthenticatedUsers, UnauthenticatedBans, Cosmetics, UserCSS, set_titan_token, get_titan_token
|
||||||
from titanembeds.oauth import authorize_url, token_url, make_authenticated_session, get_current_authenticated_user, get_user_managed_servers, check_user_can_administrate_guild, check_user_permission, generate_avatar_url, generate_guild_icon_url, generate_bot_invite_url
|
from titanembeds.oauth import authorize_url, token_url, make_authenticated_session, get_current_authenticated_user, get_user_managed_servers, check_user_can_administrate_guild, check_user_permission, generate_avatar_url, generate_guild_icon_url, generate_bot_invite_url
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
|
import paypalrestsdk
|
||||||
|
|
||||||
user = Blueprint("user", __name__)
|
user = Blueprint("user", __name__)
|
||||||
|
|
||||||
@ -70,7 +72,10 @@ def dashboard():
|
|||||||
css_list = None
|
css_list = None
|
||||||
if cosmetics and cosmetics.css:
|
if cosmetics and cosmetics.css:
|
||||||
css_list = db.session.query(UserCSS).filter(UserCSS.user_id == session['user_id']).all()
|
css_list = db.session.query(UserCSS).filter(UserCSS.user_id == session['user_id']).all()
|
||||||
return render_template("dashboard.html.j2", servers=guilds, icon_generate=generate_guild_icon_url, cosmetics=cosmetics, css_list=css_list)
|
tokens = get_titan_token(session["user_id"])
|
||||||
|
if tokens == -1:
|
||||||
|
tokens = 0
|
||||||
|
return render_template("dashboard.html.j2", servers=guilds, icon_generate=generate_guild_icon_url, cosmetics=cosmetics, css_list=css_list, tokens=tokens)
|
||||||
|
|
||||||
@user.route("/custom_css/new", methods=["GET"])
|
@user.route("/custom_css/new", methods=["GET"])
|
||||||
@discord_users_only()
|
@discord_users_only()
|
||||||
@ -322,3 +327,69 @@ def revoke_unauthenticated_user():
|
|||||||
abort(409)
|
abort(409)
|
||||||
db_user.revokeUser()
|
db_user.revokeUser()
|
||||||
return ('', 204)
|
return ('', 204)
|
||||||
|
|
||||||
|
@user.route('/donate', methods=["GET"])
|
||||||
|
@discord_users_only()
|
||||||
|
def donate_get():
|
||||||
|
return render_template('donate.html.j2')
|
||||||
|
|
||||||
|
def get_paypal_api():
|
||||||
|
return paypalrestsdk.Api({
|
||||||
|
'mode': 'sandbox' if app.config["DEBUG"] else 'live',
|
||||||
|
'client_id': config["paypal-client-id"],
|
||||||
|
'client_secret': config["paypal-client-secret"]})
|
||||||
|
|
||||||
|
@user.route('/donate', methods=['POST'])
|
||||||
|
@discord_users_only()
|
||||||
|
def donate_post():
|
||||||
|
donation_amount = request.form.get('amount')
|
||||||
|
if not donation_amount:
|
||||||
|
abort(402)
|
||||||
|
|
||||||
|
donation_amount = "{0:.2f}".format(float(donation_amount))
|
||||||
|
payer = {"payment_method": "paypal"}
|
||||||
|
items = [{"name": "TitanEmbeds Donation",
|
||||||
|
"price": donation_amount,
|
||||||
|
"currency": "USD",
|
||||||
|
"quantity": "1"}]
|
||||||
|
amount = {"total": donation_amount,
|
||||||
|
"currency": "USD"}
|
||||||
|
description = "Donate and support TitanEmbeds development."
|
||||||
|
redirect_urls = {"return_url": url_for('user.donate_confirm', success="true", _external=True),
|
||||||
|
"cancel_url": url_for('index', _external=True)}
|
||||||
|
payment = paypalrestsdk.Payment({"intent": "sale",
|
||||||
|
"payer": payer,
|
||||||
|
"redirect_urls": redirect_urls,
|
||||||
|
"transactions": [{"item_list": {"items":
|
||||||
|
items},
|
||||||
|
"amount": amount,
|
||||||
|
"description":
|
||||||
|
description}]}, api=get_paypal_api())
|
||||||
|
if payment.create():
|
||||||
|
for link in payment.links:
|
||||||
|
if link['method'] == "REDIRECT":
|
||||||
|
return redirect(link["href"])
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
@user.route("/donate/confirm")
|
||||||
|
@discord_users_only()
|
||||||
|
def donate_confirm():
|
||||||
|
if not request.args.get('success'):
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
payment = paypalrestsdk.Payment.find(request.args.get('paymentId'), api=get_paypal_api())
|
||||||
|
if payment.execute({"payer_id": request.args.get('PayerID')}):
|
||||||
|
trans_id = str(payment.transactions[0]["related_resources"][0]["sale"]["id"])
|
||||||
|
amount = float(payment.transactions[0]["amount"]["total"])
|
||||||
|
tokens = int(amount * 100)
|
||||||
|
action = "PAYPAL {}".format(trans_id)
|
||||||
|
set_titan_token(session["user_id"], tokens, action)
|
||||||
|
return redirect(url_for('user.donate_thanks', transaction=trans_id))
|
||||||
|
else:
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
@user.route("/donate/thanks")
|
||||||
|
@discord_users_only()
|
||||||
|
def donate_thanks():
|
||||||
|
tokens = get_titan_token(session["user_id"])
|
||||||
|
transaction = request.args.get("transaction")
|
||||||
|
return render_template("donate_thanks.html.j2", tokens=tokens, transaction=transaction)
|
@ -12,3 +12,24 @@ from messages import Messages, get_channel_messages
|
|||||||
from cosmetics import Cosmetics
|
from cosmetics import Cosmetics
|
||||||
from user_css import UserCSS
|
from user_css import UserCSS
|
||||||
from administrators import Administrators, get_administrators_list
|
from administrators import Administrators, get_administrators_list
|
||||||
|
from titan_tokens import TitanTokens, get_titan_token
|
||||||
|
from token_transactions import TokenTransactions
|
||||||
|
|
||||||
|
def set_titan_token(user_id, amt_change, action):
|
||||||
|
token_count = get_titan_token(user_id)
|
||||||
|
if token_count >= 0:
|
||||||
|
token_usr = db.session.query(TitanTokens).filter(TitanTokens.user_id == user_id).first()
|
||||||
|
else:
|
||||||
|
token_count = 0
|
||||||
|
token_usr = TitanTokens(user_id, 0)
|
||||||
|
db.session.add(token_usr)
|
||||||
|
db.session.commit()
|
||||||
|
new_token_count = token_count + amt_change
|
||||||
|
if new_token_count < 0:
|
||||||
|
return False
|
||||||
|
transact = TokenTransactions(user_id, action, amt_change, token_count, new_token_count)
|
||||||
|
db.session.add(transact)
|
||||||
|
token_usr.tokens = new_token_count
|
||||||
|
db.session.add(token_usr)
|
||||||
|
db.session.commit()
|
||||||
|
return True
|
18
webapp/titanembeds/database/titan_tokens.py
Normal file
18
webapp/titanembeds/database/titan_tokens.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from titanembeds.database import db
|
||||||
|
|
||||||
|
class TitanTokens(db.Model):
|
||||||
|
__tablename__ = "titan_tokens"
|
||||||
|
id = db.Column(db.Integer, primary_key=True) # Auto increment id
|
||||||
|
user_id = db.Column(db.String(255), nullable=False) # Discord user id of user
|
||||||
|
tokens = db.Column(db.Integer, nullable=False, default=0) # Token amount
|
||||||
|
|
||||||
|
def __init__(self, user_id, tokens):
|
||||||
|
self.user_id = user_id
|
||||||
|
self.tokens = tokens
|
||||||
|
|
||||||
|
def get_titan_token(user_id):
|
||||||
|
q = db.session.query(TitanTokens).filter(TitanTokens.user_id == user_id).first()
|
||||||
|
if q:
|
||||||
|
return q.tokens
|
||||||
|
else:
|
||||||
|
return -1
|
21
webapp/titanembeds/database/token_transactions.py
Normal file
21
webapp/titanembeds/database/token_transactions.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from titanembeds.database import db
|
||||||
|
import datetime
|
||||||
|
import time
|
||||||
|
|
||||||
|
class TokenTransactions(db.Model):
|
||||||
|
__tablename__ = "token_transactions"
|
||||||
|
id = db.Column(db.Integer, primary_key=True) # Auto increment id
|
||||||
|
user_id = db.Column(db.String(255), nullable=False) # Discord user id of user
|
||||||
|
timestamp = db.Column(db.TIMESTAMP, nullable=False) # The timestamp of when the action took place
|
||||||
|
action = db.Column(db.String(255), nullable=False) # Very short description of the action
|
||||||
|
net_tokens = db.Column(db.Integer, nullable=False) # Net change of the token amount
|
||||||
|
start_tokens = db.Column(db.Integer, nullable=False) # Token amount before transaction
|
||||||
|
end_tokens = db.Column(db.Integer, nullable=False) # Tokens after transaction
|
||||||
|
|
||||||
|
def __init__(self, user_id, action, net_tokens, start_tokens, end_tokens):
|
||||||
|
self.user_id = user_id
|
||||||
|
self.timestamp = datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
self.action = action
|
||||||
|
self.net_tokens = net_tokens
|
||||||
|
self.start_tokens = start_tokens
|
||||||
|
self.end_tokens = end_tokens
|
56
webapp/titanembeds/static/js/admin_token_transactions.js
Normal file
56
webapp/titanembeds/static/js/admin_token_transactions.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/* global $, Materialize, location */
|
||||||
|
|
||||||
|
function postForm(user_id, amount) {
|
||||||
|
var funct = $.ajax({
|
||||||
|
dataType: "json",
|
||||||
|
method: "POST",
|
||||||
|
data: {"user_id": user_id, "amount": amount}
|
||||||
|
});
|
||||||
|
return funct.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function patchForm(user_id, amount) {
|
||||||
|
var funct = $.ajax({
|
||||||
|
dataType: "json",
|
||||||
|
method: "PATCH",
|
||||||
|
data: {"user_id": user_id, "amount": amount}
|
||||||
|
});
|
||||||
|
return funct.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
$("#new_submit").click(function () {
|
||||||
|
var user_id = $("#new_user_id").val();
|
||||||
|
var user_token = $("#new_user_token").val();
|
||||||
|
if (user_id.length < 1 || user_token.length < 1) {
|
||||||
|
Materialize.toast("The user ID or balance field can't be blank!", 2000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var formPost = postForm(user_id, user_token);
|
||||||
|
formPost.done(function (data) {
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
|
formPost.fail(function (data) {
|
||||||
|
if (data.status == 409) {
|
||||||
|
Materialize.toast('This user id already exists!', 10000);
|
||||||
|
} else {
|
||||||
|
Materialize.toast('Oh no! Something has failed submitting a new entry!', 10000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function submit_modify_user(user_id) {
|
||||||
|
var amount = $("#input_"+user_id).val();
|
||||||
|
var formPatch = patchForm(user_id, amount);
|
||||||
|
formPatch.done(function (data) {
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
|
formPatch.fail(function (data) {
|
||||||
|
if (data.status == 409) {
|
||||||
|
Materialize.toast('This user id does not exists!', 10000);
|
||||||
|
} else {
|
||||||
|
Materialize.toast('Oh no! Something has failed changing the css toggle!', 10000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
19
webapp/titanembeds/static/js/donate.js
Normal file
19
webapp/titanembeds/static/js/donate.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* global $ */
|
||||||
|
(function () {
|
||||||
|
$('#token-slider').on('input', function(){
|
||||||
|
var slider_value = $("#token-slider").val();
|
||||||
|
var multiplier = 100;
|
||||||
|
|
||||||
|
$("#money-display").text(slider_value);
|
||||||
|
$("#token-display").text(slider_value * multiplier);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#donate-btn").click(function () {
|
||||||
|
var slider_value = $("#token-slider").val();
|
||||||
|
var form = $('<form method="POST">' +
|
||||||
|
'<input type="hidden" name="amount" value="' + slider_value + '">' +
|
||||||
|
'</form>');
|
||||||
|
$(document.body).append(form);
|
||||||
|
form.submit();
|
||||||
|
});
|
||||||
|
})();
|
@ -20,6 +20,13 @@
|
|||||||
<a class="waves-effect waves-light btn" href="{{ url_for('admin.guilds') }}">Manage</a>
|
<a class="waves-effect waves-light btn" href="{{ url_for('admin.guilds') }}">Manage</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col s12">
|
||||||
|
<div class="card-panel indigo lighten-5 z-depth-3 hoverable black-text">
|
||||||
|
<h4>Titan Tokens</h4>
|
||||||
|
<p class="flow-text">View transactions and modify Titan Tokens per user.</p>
|
||||||
|
<a class="waves-effect waves-light btn" href="{{ url_for('admin.manage_titan_tokens') }}">Manage</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="col s12">
|
<div class="col s12">
|
||||||
<div class="card-panel indigo lighten-5 z-depth-3 hoverable black-text">
|
<div class="card-panel indigo lighten-5 z-depth-3 hoverable black-text">
|
||||||
<h4>Run a Database Cleanup</h4>
|
<h4>Run a Database Cleanup</h4>
|
||||||
|
105
webapp/titanembeds/templates/admin_token_transactions.html.j2
Normal file
105
webapp/titanembeds/templates/admin_token_transactions.html.j2
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
{% extends 'site_layout.html.j2' %}
|
||||||
|
{% set title="Editing User Titan Tokens" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Administrating Titan Tokens</h1>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12">
|
||||||
|
<div class="card-panel indigo lighten-5 z-depth-3 hoverable black-text">
|
||||||
|
<p class="flow-text">New Entry</p>
|
||||||
|
<table class="bordered striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>User ID</th>
|
||||||
|
<th>Starting Balance</th>
|
||||||
|
<th>Submit</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div class="input-field inline">
|
||||||
|
<input id="new_user_id" placeholder="User ID">
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="input-field inline">
|
||||||
|
<input id="new_user_token" placeholder="Starting Balance" type="number">
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a class="waves-effect waves-light btn" id="new_submit">Submit</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12">
|
||||||
|
<div class="card-panel indigo lighten-5 z-depth-3 hoverable black-text">
|
||||||
|
<p class="flow-text">View Transactions and Modify User Tokens</p>
|
||||||
|
<ul class="collapsible" data-collapsible="accordion">
|
||||||
|
{% for don in donators %}
|
||||||
|
<li>
|
||||||
|
<div class="collapsible-header">{{ don.user_id }}</div>
|
||||||
|
<div class="collapsible-body">
|
||||||
|
|
||||||
|
<table class="bordered striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Modify Amount</th>
|
||||||
|
<th>Submit</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div class="input-field inline">
|
||||||
|
<input placeholder="Modify Amount" type="number" id="input_{{ don.user_id }}">
|
||||||
|
</div>
|
||||||
|
<p>(Place a subtract sign in the front to remove tokens. Otherwise, it will add the amount)</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a class="waves-effect waves-light btn" onclick="submit_modify_user('{{ don.user_id }}')">Submit</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4>Balance: <strong>{{ don.tokens }}</strong> Tokens</h4>
|
||||||
|
<table class="striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Trans #</th>
|
||||||
|
<th>Timestamp</th>
|
||||||
|
<th>Action</th>
|
||||||
|
<th>Change</th>
|
||||||
|
<th>Starting Bal</th>
|
||||||
|
<th>Ending Bal</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for trans in don.transactions %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ trans.id }}</td>
|
||||||
|
<td>{{ trans.timestamp }}</td>
|
||||||
|
<td>{{ trans.action }}.</td>
|
||||||
|
<td>{{ trans.net_tokens }}</td>
|
||||||
|
<td>{{ trans.start_tokens }}</td>
|
||||||
|
<td>{{ trans.end_tokens }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
{% block script %}
|
||||||
|
<script type="text/javascript" src="{{ url_for('static', filename='js/admin_token_transactions.js') }}"></script>
|
||||||
|
{% endblock %}
|
@ -2,7 +2,6 @@
|
|||||||
{% set title="Dashboard" %}
|
{% set title="Dashboard" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% include 'patreon_banner.html.j2' %}
|
|
||||||
<h1>User Dashboard</h1>
|
<h1>User Dashboard</h1>
|
||||||
<p class="flow-text">Select a server to configure Titan Embeds.</p>
|
<p class="flow-text">Select a server to configure Titan Embeds.</p>
|
||||||
<p>*List missing some servers? It's because you must have either <strong>Manage Server</strong>, <strong>Kick Members</strong>, or <strong>Ban Members</strong> permissions to modify embed settings.</p>
|
<p>*List missing some servers? It's because you must have either <strong>Manage Server</strong>, <strong>Kick Members</strong>, or <strong>Ban Members</strong> permissions to modify embed settings.</p>
|
||||||
@ -61,4 +60,17 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12">
|
||||||
|
<div class="card-panel indigo lighten-5 z-depth-3 hoverable black-text">
|
||||||
|
<h4>Donations!</h4>
|
||||||
|
<p class="flow-text">Would you like to support the Titan Embeds project?</p>
|
||||||
|
<p>You currently have <strong>{{ tokens }}</strong> Titan Tokens.</p>
|
||||||
|
<a class="waves-effect waves-light btn" href="{{ url_for('user.donate_get') }}">Donate!!</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
51
webapp/titanembeds/templates/donate.html.j2
Normal file
51
webapp/titanembeds/templates/donate.html.j2
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
{% extends 'site_layout.html.j2' %}
|
||||||
|
{% set title="Donate" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Donate and Support Titan Embeds</h1>
|
||||||
|
<p class="flow-text">Contributing to the Titan project has never been so easy! Donate to support our project development and hosting.</p>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12">
|
||||||
|
<div class="card-panel indigo lighten-5 z-depth-3 hoverable black-text">
|
||||||
|
<h4>The Name-Your-Price Tool</h4>
|
||||||
|
<p class="flow-text">Currently if you donate, we cannot give much back in return, yet. However, we do have some donatator features up our sleeves and will be implemented.</p>
|
||||||
|
<p class="flow-text">For now, you will receive <strong>Titan Tokens™</strong> (to be spent on donator features) and a <strong>supporter role</strong> on our support server.</p>
|
||||||
|
<p class="range-field">
|
||||||
|
<input type="range" id="token-slider" min="1" max="100" value="5" />
|
||||||
|
</p>
|
||||||
|
<p class="flow-text">$<span id="money-display">5</span> for <strong><span id="token-display">500</span> tokens</strong>!</p>
|
||||||
|
<a class="waves-effect waves-light btn" id="donate-btn">Donate</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
{% block script %}
|
||||||
|
<script type="text/javascript" src="{{ url_for('static', filename='js/donate.js') }}"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block additional_head_elements %}
|
||||||
|
<style>
|
||||||
|
input[type=range]::-webkit-slider-thumb {
|
||||||
|
background-color: #303f9f;
|
||||||
|
}
|
||||||
|
input[type=range]::-moz-range-thumb {
|
||||||
|
background-color: #303f9f;
|
||||||
|
}
|
||||||
|
input[type=range]::-ms-thumb {
|
||||||
|
background-color: #303f9f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** These are to edit the thumb and the text inside the thumb *****/
|
||||||
|
input[type=range] + .thumb {
|
||||||
|
background-color: #dedede;
|
||||||
|
}
|
||||||
|
input[type=range] + .thumb.active .value {
|
||||||
|
font-size: 12pt;
|
||||||
|
color: #303f9f;
|
||||||
|
}
|
||||||
|
input[type=range] + .thumb.active .value::before {
|
||||||
|
content: "$";
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
18
webapp/titanembeds/templates/donate_thanks.html.j2
Normal file
18
webapp/titanembeds/templates/donate_thanks.html.j2
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{% extends 'site_layout.html.j2' %}
|
||||||
|
{% set title="Thanks for Donating" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Thank you for Donating and Supporting the Titan Embeds project!</h1>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12">
|
||||||
|
<div class="card-panel indigo lighten-5 z-depth-3 hoverable black-text">
|
||||||
|
<h4>You're officially one step closer to becoming a True Titan!</h4>
|
||||||
|
<p class="flow-text">You now have <strong>{{ tokens }}</strong> tokens!</p>
|
||||||
|
<p>Please visit our support server and contact a True Titan (Administrators Role) to claim your Supporter role, if you haven't done so already. Mention the transaction ID of <strong>{{ transaction }}</strong>.</p>
|
||||||
|
<a class="waves-effect waves-light btn" href="https://discord.io/Titan" target="_blank">Support Server</a>
|
||||||
|
<p><em>Have a nice day!</em></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -2,7 +2,6 @@
|
|||||||
{% set title="Index" %}
|
{% set title="Index" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% include 'patreon_banner.html.j2' %}
|
|
||||||
<h1 class="center-align">Embed Discord like a<br><strong>true Titan</strong></h1>
|
<h1 class="center-align">Embed Discord like a<br><strong>true Titan</strong></h1>
|
||||||
<p class="flow-text center-align">Add <strong>Titan</strong> to your discord server to create your own personalized chat embed!</p>
|
<p class="flow-text center-align">Add <strong>Titan</strong> to your discord server to create your own personalized chat embed!</p>
|
||||||
<a class="waves-effect waves-light btn btn-large center_content" href="{{ url_for('user.dashboard') }}">Start here!</a>
|
<a class="waves-effect waves-light btn btn-large center_content" href="{{ url_for('user.dashboard') }}">Start here!</a>
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
<div class="collection">
|
|
||||||
<a href="https://www.patreon.com/TitanEmbeds" class="collection-item"><i class="material-icons">monetization_on</i> We have decided to open a Patreon page to help fund the Titan. If you are interested and would like to help, please check it out!</a>
|
|
||||||
</div>
|
|
Loading…
Reference in New Issue
Block a user