mirror of
				https://github.com/TitanEmbeds/Titan.git
				synced 2025-11-03 23:37:09 +01:00 
			
		
		
		
	Paypal (#41)
* Implement Titan Tokens clientside * Titan Tokens can be modified in the admin panel
This commit is contained in:
		
				
					committed by
					
						
						GitHub
					
				
			
			
				
	
			
			
			
						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>
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user