diff --git a/discordbot/titanembeds/database/guilds.py b/discordbot/titanembeds/database/guilds.py index 233cd0b..11abe96 100644 --- a/discordbot/titanembeds/database/guilds.py +++ b/discordbot/titanembeds/database/guilds.py @@ -8,6 +8,7 @@ class Guilds(Base): unauth_users = db.Column(db.Boolean()) # If allowed unauth users visitor_view = db.Column(db.Boolean()) # If users are automatically "signed in" and can view chat webhook_messages = db.Column(db.Boolean()) # Use webhooks to send messages instead of the bot + webhook_icon = db.Column(db.String(255), default=None) # Webhook icon url, None if unset chat_links = db.Column(db.Boolean()) # If users can post links bracket_links = db.Column(db.Boolean()) # If appending brackets to links to prevent embed mentions_limit = db.Column(db.Integer) # If there is a limit on the number of mentions in a msg @@ -25,6 +26,7 @@ class Guilds(Base): self.unauth_users = True # defaults to true self.visitor_view = False self.webhook_messages = False + self.webhook_icon = None self.chat_links = True self.bracket_links = True self.mentions_limit = -1 # -1 = unlimited mentions diff --git a/webapp/alembic/versions/39815dfbcccb_added_webhook_icon_column_to_guilds_and_.py b/webapp/alembic/versions/39815dfbcccb_added_webhook_icon_column_to_guilds_and_.py new file mode 100644 index 0000000..b914168 --- /dev/null +++ b/webapp/alembic/versions/39815dfbcccb_added_webhook_icon_column_to_guilds_and_.py @@ -0,0 +1,30 @@ +"""Added webhook icon column to guilds and cosmetics + +Revision ID: 39815dfbcccb +Revises: d1b89c41bf16 +Create Date: 2017-09-13 04:31:35.532918 + +""" + +# revision identifiers, used by Alembic. +revision = '39815dfbcccb' +down_revision = 'd1b89c41bf16' +branch_labels = None +depends_on = None + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('cosmetics', sa.Column('webhook_icon', sa.Boolean(), server_default=sa.text('false'), nullable=False)) + op.add_column('guilds', sa.Column('webhook_icon', sa.String(length=255), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('guilds', 'webhook_icon') + op.drop_column('cosmetics', 'webhook_icon') + # ### end Alembic commands ### diff --git a/webapp/titanembeds/blueprints/admin/admin.py b/webapp/titanembeds/blueprints/admin/admin.py index 420a870..0f93685 100644 --- a/webapp/titanembeds/blueprints/admin/admin.py +++ b/webapp/titanembeds/blueprints/admin/admin.py @@ -36,7 +36,8 @@ def cosmetics_post(): if not user_id: abort(400) css = request.form.get("css", None) - css_limit = request.form.get("css_limit", None) + css_limit = int(request.form.get("css_limit", 0)) + webhook_icon = request.form.get("webhook_icon", None) entry = db.session.query(Cosmetics).filter(Cosmetics.user_id == user_id).first() if entry: abort(409) @@ -46,6 +47,9 @@ def cosmetics_post(): user.css = css if css_limit is not None: user.css_limit = css_limit + if webhook_icon is not None: + webhook_icon = webhook_icon.lower() == "true" + user.webhook_icon = webhook_icon db.session.add(user) db.session.commit() return ('', 204) @@ -71,6 +75,7 @@ def cosmetics_patch(): abort(400) css = request.form.get("css", None) css_limit = request.form.get("css_limit", None) + webhook_icon = request.form.get("webhook_icon", None) entry = db.session.query(Cosmetics).filter(Cosmetics.user_id == user_id).first() if not entry: abort(409) @@ -79,6 +84,9 @@ def cosmetics_patch(): entry.css = css if css_limit is not None: entry.css_limit = css_limit + if webhook_icon: + webhook_icon = webhook_icon.lower() == "true" + entry.webhook_icon = webhook_icon db.session.commit() return ('', 204) def prepare_guild_members_list(members, bans): @@ -129,6 +137,7 @@ def administrate_guild(guild_id): abort(500) return session["redirect"] = None + cosmetics = db.session.query(Cosmetics).filter(Cosmetics.user_id == session['user_id']).first() permissions=[] permissions.append("Manage Embed Settings") permissions.append("Ban Members") @@ -146,9 +155,10 @@ def administrate_guild(guild_id): "bracket_links": db_guild.bracket_links, "mentions_limit": db_guild.mentions_limit, "icon": db_guild.icon, - "discordio": db_guild.discordio if db_guild.discordio != None else "" + "discordio": db_guild.discordio if db_guild.discordio != None else "", + "webhook_icon": db_guild.webhook_icon if db_guild.webhook_icon != None else "", } - return render_template("administrate_guild.html.j2", guild=dbguild_dict, members=users, permissions=permissions) + return render_template("administrate_guild.html.j2", guild=dbguild_dict, members=users, permissions=permissions, cosmetics=cosmetics) @admin.route("/administrate_guild/", methods=["POST"]) @is_admin @@ -161,9 +171,14 @@ def update_administrate_guild(guild_id): db_guild.bracket_links = request.form.get("bracket_links", db_guild.bracket_links) in ["true", True] db_guild.mentions_limit = request.form.get("mentions_limit", db_guild.mentions_limit) discordio = request.form.get("discordio", db_guild.discordio) - if discordio and discordio.strip() == "": + if discordio != None and discordio.strip() == "": discordio = None db_guild.discordio = discordio + webhook_icon = request.form.get("webhook_icon", db_guild.webhook_icon) + if webhook_icon != None and webhook_icon.strip() == "": + webhook_icon = None + db_guild.webhook_icon = webhook_icon + print(webhook_icon) db.session.commit() return jsonify( id=db_guild.id, @@ -175,6 +190,7 @@ def update_administrate_guild(guild_id): bracket_links=db_guild.bracket_links, mentions_limit=db_guild.mentions_limit, discordio=db_guild.discordio, + webhook_icon=db_guild.webhook_icon, ) @admin.route("/guilds") diff --git a/webapp/titanembeds/blueprints/api/api.py b/webapp/titanembeds/blueprints/api/api.py index 6392ab3..cee2a6b 100644 --- a/webapp/titanembeds/blueprints/api/api.py +++ b/webapp/titanembeds/blueprints/api/api.py @@ -246,6 +246,11 @@ def post(): if (session['unauthenticated']): username = session["username"] + "#" + str(session["user_id"]) avatar = url_for('static', filename='img/titanembeds_round.png', _external=True) + dbguild = db.session.query(Guilds).filter(Guilds.guild_id == guild_id).first() + if dbguild: + icon = dbguild.webhook_icon + if icon: + avatar = icon else: username = session["username"] if dbUser: diff --git a/webapp/titanembeds/blueprints/user/user.py b/webapp/titanembeds/blueprints/user/user.py index 4884cb9..c2570d1 100644 --- a/webapp/titanembeds/blueprints/user/user.py +++ b/webapp/titanembeds/blueprints/user/user.py @@ -196,6 +196,7 @@ def administrate_guild(guild_id): permissions.append("Ban Members") if check_user_permission(guild_id, 1): permissions.append("Kick Members") + cosmetics = db.session.query(Cosmetics).filter(Cosmetics.user_id == session['user_id']).first() all_members = db.session.query(UnauthenticatedUsers).filter(UnauthenticatedUsers.guild_id == guild_id).order_by(UnauthenticatedUsers.last_timestamp).all() all_bans = db.session.query(UnauthenticatedBans).filter(UnauthenticatedBans.guild_id == guild_id).all() users = prepare_guild_members_list(all_members, all_bans) @@ -209,9 +210,10 @@ def administrate_guild(guild_id): "bracket_links": db_guild.bracket_links, "mentions_limit": db_guild.mentions_limit, "icon": db_guild.icon, - "discordio": db_guild.discordio if db_guild.discordio != None else "" + "discordio": db_guild.discordio if db_guild.discordio != None else "", + "webhook_icon": db_guild.webhook_icon if db_guild.webhook_icon != None else "", } - return render_template("administrate_guild.html.j2", guild=dbguild_dict, members=users, permissions=permissions) + return render_template("administrate_guild.html.j2", guild=dbguild_dict, members=users, permissions=permissions, cosmetics=cosmetics) @user.route("/administrate_guild/", methods=["POST"]) @discord_users_only() @@ -229,9 +231,15 @@ def update_administrate_guild(guild_id): db_guild.mentions_limit = request.form.get("mentions_limit", db_guild.mentions_limit) discordio = request.form.get("discordio", db_guild.discordio) - if discordio and discordio.strip() == "": + if discordio != None and discordio.strip() == "": discordio = None db_guild.discordio = discordio + + webhook_icon = request.form.get("webhook_icon", db_guild.webhook_icon) + if webhook_icon != None and webhook_icon.strip() == "": + webhook_icon = None + db_guild.webhook_icon = webhook_icon + db.session.commit() return jsonify( id=db_guild.id, @@ -243,6 +251,7 @@ def update_administrate_guild(guild_id): bracket_links=db_guild.bracket_links, mentions_limit=db_guild.mentions_limit, discordio=db_guild.discordio, + webhook_icon=webhook_icon, ) @user.route("/add-bot/") @@ -358,7 +367,8 @@ def revoke_unauthenticated_user(): @user.route('/donate', methods=["GET"]) @discord_users_only() def donate_get(): - return render_template('donate.html.j2') + cosmetics = db.session.query(Cosmetics).filter(Cosmetics.user_id == session["user_id"]).first() + return render_template('donate.html.j2', cosmetics=cosmetics) def get_paypal_api(): return paypalrestsdk.Api({ @@ -430,20 +440,28 @@ def donate_patch(): if amount <= 0: abort(400) subtract_amt = 0 + entry = db.session.query(Cosmetics).filter(Cosmetics.user_id == session["user_id"]).first() if item == "custom_css_slots": subtract_amt = 100 + if item == "webhook_icon": + subtract_amt = 300 + if entry is not None and entry.webhook_icon: + abort(400) amt_change = -1 * subtract_amt * amount subtract = set_titan_token(session["user_id"], amt_change, "BUY " + item + " x" + str(amount)) if not subtract: return ('', 402) session["tokens"] += amt_change if item == "custom_css_slots": - entry = db.session.query(Cosmetics).filter(Cosmetics.user_id == session["user_id"]).first() if not entry: entry = Cosmetics(session["user_id"]) entry.css = True entry.css_limit = 0 entry.css_limit += amount - db.session.add(entry) - db.session.commit() + if item == "webhook_icon": + if not entry: + entry = Cosmetics(session["user_id"]) + entry.webhook_icon = True + db.session.add(entry) + db.session.commit() return ('', 204) \ No newline at end of file diff --git a/webapp/titanembeds/database/cosmetics.py b/webapp/titanembeds/database/cosmetics.py index e931822..df225ac 100644 --- a/webapp/titanembeds/database/cosmetics.py +++ b/webapp/titanembeds/database/cosmetics.py @@ -6,6 +6,7 @@ class Cosmetics(db.Model): user_id = db.Column(db.String(255), nullable=False) # Discord user id of user of cosmetics css = db.Column(db.Boolean(), nullable=False) # If they can create/edit custom CSS css_limit = db.Column(db.Integer, nullable=False, server_default="0") # Custom CSS Limit + webhook_icon = db.Column(db.Boolean(), nullable=False, server_default=db.false()) # If they can set the webhook icon for all guilds def __init__(self, user_id, **kwargs): self.user_id = user_id @@ -19,3 +20,8 @@ class Cosmetics(db.Model): self.css_limit = kwargs["css_limit"] else: self.css_limit = 0 + + if "webhook_icon" in kwargs: + self.webhook_icon = kwargs["webhook_icon"] + else: + self.webhook_icon = False \ No newline at end of file diff --git a/webapp/titanembeds/database/guilds.py b/webapp/titanembeds/database/guilds.py index bf34715..980521d 100644 --- a/webapp/titanembeds/database/guilds.py +++ b/webapp/titanembeds/database/guilds.py @@ -8,6 +8,7 @@ class Guilds(db.Model): unauth_users = db.Column(db.Boolean(), nullable=False, default=1) # If allowed unauth users visitor_view = db.Column(db.Boolean(), nullable=False, default=0) # If users are automatically "signed in" and can view chat webhook_messages = db.Column(db.Boolean(), nullable=False, default=0) # Use webhooks to send messages instead of the bot + webhook_icon = db.Column(db.String(255), default=None) # Webhook icon url, None if unset chat_links = db.Column(db.Boolean(), nullable=False, default=1) # If users can post links bracket_links = db.Column(db.Boolean(), nullable=False, default=1) # If appending brackets to links to prevent embed mentions_limit = db.Column(db.Integer, nullable=False, default=11) # If there is a limit on the number of mentions in a msg @@ -25,6 +26,7 @@ class Guilds(db.Model): self.unauth_users = True # defaults to true self.visitor_view = False self.webhook_messages = False + self.webhook_icon = None self.chat_links = True self.bracket_links = True self.mentions_limit = -1 # -1 = unlimited mentions diff --git a/webapp/titanembeds/static/js/admin_cosmetics.js b/webapp/titanembeds/static/js/admin_cosmetics.js index 4941957..14c4837 100644 --- a/webapp/titanembeds/static/js/admin_cosmetics.js +++ b/webapp/titanembeds/static/js/admin_cosmetics.js @@ -1,10 +1,13 @@ /* global $, Materialize, location */ -function postForm(user_id, css) { +function postForm(user_id, css, css_limit, webhook_icon) { + if (css_limit == "") { + css_limit = 0; + } var funct = $.ajax({ dataType: "json", method: "POST", - data: {"user_id": user_id, "css": css} + data: {"user_id": user_id, "css": css, "css_limit": css_limit, "webhook_icon": webhook_icon} }); return funct.promise(); } @@ -36,7 +39,9 @@ $(function() { return; } var css_checked = $("#new_css_switch").is(':checked'); - var formPost = postForm(user_id, css_checked); + var css_limit = $("#new_css_limit").val(); + var webhook_icon_checked = $("#new_webhook_icon_switch").is(':checked'); + var formPost = postForm(user_id, css_checked, css_limit, webhook_icon_checked); formPost.done(function (data) { location.reload(); }); @@ -94,4 +99,19 @@ function update_css_limit(user_id, value) { Materialize.toast('Oh no! Something has failed changing the css limit field!', 10000); } }); +} + +function update_webhook_icon_switch(user_id, element) { + var webhook_checked = $(element).is(':checked'); + var formPatch = patchForm(user_id, {"webhook_icon": webhook_checked}); + formPatch.done(function (data) { + Materialize.toast('Webhook Icon updated!', 10000); + }); + 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 webhook icon toggle!', 10000); + } + }); } \ No newline at end of file diff --git a/webapp/titanembeds/static/js/administrate_guild.js b/webapp/titanembeds/static/js/administrate_guild.js index c189827..59a384d 100644 --- a/webapp/titanembeds/static/js/administrate_guild.js +++ b/webapp/titanembeds/static/js/administrate_guild.js @@ -65,6 +65,17 @@ $("#discordio").keyup(function(event){ } }); +$("#webhook_icon").keyup(function(event){ + if(event.keyCode == 13){ + var pathname = window.location.pathname; + var value = $("#webhook_icon").val() + var payload = {"webhook_icon": value} + $.post(pathname, payload, function(data) { + Materialize.toast('Updated Webhook Icon setting!', 2000) + }); + } +}); + function initiate_ban(guild_id, user_id) { var reason = prompt("Please enter your reason for ban"); var payload = { diff --git a/webapp/titanembeds/static/js/donate.js b/webapp/titanembeds/static/js/donate.js index 49713d1..378174d 100644 --- a/webapp/titanembeds/static/js/donate.js +++ b/webapp/titanembeds/static/js/donate.js @@ -46,4 +46,21 @@ } }); }); + + $("#buy-webhook-guest-user-avatar-btn").click(function () { + var formPatch = patchForm("webhook_icon", 1); + formPatch.done(function (data) { + alert("Successfully bought webhook guest user avatar perk!"); + location.reload(); + }); + formPatch.fail(function (data) { + if (data.status == 400) { + Materialize.toast('Item already purchased!', 10000); + } else if (data.status == 402) { + Materialize.toast('Insufficient token funds!', 10000); + } else { + Materialize.toast('Purchasing webhook guest user avatar perk failed!', 10000); + } + }); + }); })(); \ No newline at end of file diff --git a/webapp/titanembeds/templates/admin_cosmetics.html.j2 b/webapp/titanembeds/templates/admin_cosmetics.html.j2 index ca4a07b..56266ff 100644 --- a/webapp/titanembeds/templates/admin_cosmetics.html.j2 +++ b/webapp/titanembeds/templates/admin_cosmetics.html.j2 @@ -14,6 +14,7 @@ User ID CSS CSS Limit + Webhook Icon Submit @@ -24,6 +25,16 @@ + +
+ +
+
@@ -33,7 +44,7 @@
@@ -57,6 +68,7 @@ User ID CSS CSS Limit + Webhook Icon @@ -79,6 +91,16 @@
+ +
+ +
+ {% endfor %} diff --git a/webapp/titanembeds/templates/administrate_guild.html.j2 b/webapp/titanembeds/templates/administrate_guild.html.j2 index 2adb547..a598ca4 100644 --- a/webapp/titanembeds/templates/administrate_guild.html.j2 +++ b/webapp/titanembeds/templates/administrate_guild.html.j2 @@ -112,6 +112,16 @@

Because we are a partner with Discord.io, we enable you to enter your custom discord.io link and replace the discord.gg link on the embed!

(Leave blank if none - enter to submit)

+ +
+ +

Webhook Guest User Avatar URL

+

If enabled Webhook Messages, you may set it so that the guest users may have a custom avatar instead of the Titan logo. Source must be the permanent URL location to the image file (try imgur and get direct link to image).

+

(Leave blank if none - enter to submit)

+ {% if not cosmetics.webhook_icon %} +

Your user account does not have access to change webhook avatar url. Please visit the Titan Tokens shop to activate this cosmetic item.

+ {% endif %} +
diff --git a/webapp/titanembeds/templates/dashboard.html.j2 b/webapp/titanembeds/templates/dashboard.html.j2 index 02db48c..63ae2ba 100644 --- a/webapp/titanembeds/templates/dashboard.html.j2 +++ b/webapp/titanembeds/templates/dashboard.html.j2 @@ -32,13 +32,14 @@
-{% if cosmetics is none %} +{% if (not cosmetics) or (cosmetics and not cosmetics.css) %}
-

Cosmetics!

-

Would you like to have cosmetics such as custom CSS for your embed?

+

User Defined CSS!

+

Would you like to have user defined css (e.g. custom css) for your embed?

Talk to us! +

The first slot is on the house. Increasing the slot count requires the user to spend Titan Tokens. However, we do offer unlimited predefined CSS Color Variables at no charge.

diff --git a/webapp/titanembeds/templates/donate.html.j2 b/webapp/titanembeds/templates/donate.html.j2 index 0a203c9..a364a24 100644 --- a/webapp/titanembeds/templates/donate.html.j2 +++ b/webapp/titanembeds/templates/donate.html.j2 @@ -40,6 +40,14 @@ +
+
+

Webhook Guest User Avatar [300 tokens]

+

Tired of the bland Titan logo for your guests avatars in your servers? Enables your account to be able to set webhook icons for guests for all servers you can manage.

+

(Note: Webhook Messages has to be enabled & Titan needs server permissions to create webhooks)

+ {% if cosmetics.webhook_icon %}Already Purchased{% else %}Buy{% endif %} +
+
{% endblock %} {% block script %}