From d18c9bf1c9e62513d8ecd11fe03f7d6099a31d34 Mon Sep 17 00:00:00 2001 From: Jeremy Zhang Date: Mon, 22 May 2017 01:07:32 +0000 Subject: [PATCH] Implemented Cosmetics and User Custom CSS, closes #7 --- webapp/titanembeds/blueprints/embed/embed.py | 13 ++- webapp/titanembeds/blueprints/user/user.py | 87 ++++++++++++++++++- webapp/titanembeds/database/__init__.py | 2 + webapp/titanembeds/database/cosmetics.py | 7 ++ webapp/titanembeds/database/user_css.py | 13 +++ webapp/titanembeds/static/js/usercss.js | 57 ++++++++++++ .../titanembeds/templates/dashboard.html.j2 | 31 +++++++ webapp/titanembeds/templates/embed.html.j2 | 4 + webapp/titanembeds/templates/usercss.html.j2 | 65 ++++++++++++++ 9 files changed, 274 insertions(+), 5 deletions(-) create mode 100644 webapp/titanembeds/database/cosmetics.py create mode 100644 webapp/titanembeds/database/user_css.py create mode 100644 webapp/titanembeds/static/js/usercss.js create mode 100644 webapp/titanembeds/templates/usercss.html.j2 diff --git a/webapp/titanembeds/blueprints/embed/embed.py b/webapp/titanembeds/blueprints/embed/embed.py index 30ddf76..9b68511 100644 --- a/webapp/titanembeds/blueprints/embed/embed.py +++ b/webapp/titanembeds/blueprints/embed/embed.py @@ -1,7 +1,7 @@ -from flask import Blueprint, render_template, abort, redirect, url_for, session +from flask import Blueprint, render_template, abort, redirect, url_for, session, request from titanembeds.utils import check_guild_existance, guild_query_unauth_users_bool from titanembeds.oauth import generate_guild_icon_url, generate_avatar_url -from titanembeds.database import db, Guilds +from titanembeds.database import db, Guilds, UserCSS from config import config import random @@ -20,6 +20,12 @@ def get_logingreeting(): ] return random.choice(greetings) +def get_custom_css(): + css = request.args.get("css", None) + if css: + css = db.session.query(UserCSS).filter(UserCSS.id == css).first() + return css + @embed.route("/") def guild_embed(guild_id): if check_guild_existance(guild_id): @@ -35,7 +41,8 @@ def guild_embed(guild_id): guild_id=guild_id, guild=guild_dict, generate_guild_icon=generate_guild_icon_url, unauth_enabled=guild_query_unauth_users_bool(guild_id), - client_id=config['client-id'] + client_id=config['client-id'], + css=get_custom_css() ) abort(404) diff --git a/webapp/titanembeds/blueprints/user/user.py b/webapp/titanembeds/blueprints/user/user.py index 792fbfc..0b0b32c 100644 --- a/webapp/titanembeds/blueprints/user/user.py +++ b/webapp/titanembeds/blueprints/user/user.py @@ -1,7 +1,7 @@ from flask import Blueprint, request, redirect, jsonify, abort, session, url_for, render_template from config import config from titanembeds.decorators import discord_users_only -from titanembeds.database import db, Guilds, UnauthenticatedUsers, UnauthenticatedBans +from titanembeds.database import db, Guilds, UnauthenticatedUsers, UnauthenticatedBans, Cosmetics, UserCSS 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 datetime @@ -66,7 +66,90 @@ def dashboard(): redir = session['redirect'] session['redirect'] = None return redirect(redir) - return render_template("dashboard.html.j2", servers=guilds, icon_generate=generate_guild_icon_url) + cosmetics = db.session.query(Cosmetics).filter(Cosmetics.user_id == session['user_id']).first() + css_list = None + if cosmetics and cosmetics.css: + 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) + +@user.route("/custom_css/new", methods=["GET"]) +@discord_users_only() +def new_custom_css_get(): + cosmetics = db.session.query(Cosmetics).filter(Cosmetics.user_id == session['user_id']).first() + if not cosmetics or not cosmetics.css: + abort(403) + return render_template("usercss.html.j2", new=True) + +@user.route("/custom_css/new", methods=["POST"]) +@discord_users_only() +def new_custom_css_post(): + cosmetics = db.session.query(Cosmetics).filter(Cosmetics.user_id == session['user_id']).first() + if not cosmetics or not cosmetics.css: + abort(403) + + name = request.form.get("name", None) + user_id = session["user_id"] + css = request.form.get("css","") + if not name: + abort(400) + else: + name = name.strip() + css = css.strip() + css = UserCSS(name, user_id, css) + db.session.add(css) + db.session.commit() + return jsonify({"id": css.id}) + +@user.route("/custom_css/edit/", methods=["GET"]) +@discord_users_only() +def edit_custom_css_get(css_id): + cosmetics = db.session.query(Cosmetics).filter(Cosmetics.user_id == session['user_id']).first() + if not cosmetics or not cosmetics.css: + abort(403) + css = db.session.query(UserCSS).filter(UserCSS.id == css_id).first() + if not css: + abort(404) + if css.user_id != session['user_id']: + abort(403) + return render_template("usercss.html.j2", new=False, css=css) + +@user.route("/custom_css/edit/", methods=["POST"]) +@discord_users_only() +def edit_custom_css_post(css_id): + cosmetics = db.session.query(Cosmetics).filter(Cosmetics.user_id == session['user_id']).first() + if not cosmetics or not cosmetics.css: + abort(403) + dbcss = db.session.query(UserCSS).filter(UserCSS.id == css_id).first() + if not dbcss: + abort(404) + if dbcss.user_id != session['user_id']: + abort(403) + name = request.form.get("name", None) + css = request.form.get("css", "") + if not name: + abort(400) + else: + name = name.strip() + css = css.strip() + dbcss.name = name + dbcss.css = css + db.session.commit() + return jsonify({"id": dbcss.id}) + +@user.route("/custom_css/edit/", methods=["DELETE"]) +@discord_users_only() +def edit_custom_css_delete(css_id): + cosmetics = db.session.query(Cosmetics).filter(Cosmetics.user_id == session['user_id']).first() + if not cosmetics or not cosmetics.css: + abort(403) + dbcss = db.session.query(UserCSS).filter(UserCSS.id == css_id).first() + if not dbcss: + abort(404) + if dbcss.user_id != session['user_id']: + abort(403) + db.session.delete(dbcss) + db.session.commit() + return jsonify({}) @user.route("/administrate_guild/", methods=["GET"]) @discord_users_only() diff --git a/webapp/titanembeds/database/__init__.py b/webapp/titanembeds/database/__init__.py index 34644af..0450efc 100644 --- a/webapp/titanembeds/database/__init__.py +++ b/webapp/titanembeds/database/__init__.py @@ -9,3 +9,5 @@ from authenticated_users import AuthenticatedUsers from guild_members import GuildMembers, list_all_guild_members from keyvalue_properties import KeyValueProperties, set_keyvalproperty, get_keyvalproperty, getexpir_keyvalproperty, setexpir_keyvalproperty, ifexists_keyvalproperty, delete_keyvalproperty from messages import Messages, get_channel_messages +from cosmetics import Cosmetics +from user_css import UserCSS \ No newline at end of file diff --git a/webapp/titanembeds/database/cosmetics.py b/webapp/titanembeds/database/cosmetics.py new file mode 100644 index 0000000..29e060b --- /dev/null +++ b/webapp/titanembeds/database/cosmetics.py @@ -0,0 +1,7 @@ +from titanembeds.database import db + +class Cosmetics(db.Model): + __tablename__ = "cosmetics" + id = db.Column(db.Integer, primary_key=True) # Auto increment id + user_id = db.Column(db.String(255)) # Discord user id of user of cosmetics + css = db.Column(db.Boolean()) # If they can create/edit custom CSS \ No newline at end of file diff --git a/webapp/titanembeds/database/user_css.py b/webapp/titanembeds/database/user_css.py new file mode 100644 index 0000000..f6ff743 --- /dev/null +++ b/webapp/titanembeds/database/user_css.py @@ -0,0 +1,13 @@ +from titanembeds.database import db + +class UserCSS(db.Model): + __tablename__ = "user_css" + id = db.Column(db.Integer, primary_key=True) # Auto increment id + name = db.Column(db.String(255)) # CSS Name + user_id = db.Column(db.String(255)) # Discord client ID of the owner of the css (can edit) + css = db.Column(db.Text()) # CSS contents + + def __init__(self, name, user_id, css=None): + self.name = name + self.user_id = user_id + self.css = css diff --git a/webapp/titanembeds/static/js/usercss.js b/webapp/titanembeds/static/js/usercss.js new file mode 100644 index 0000000..68f9a6b --- /dev/null +++ b/webapp/titanembeds/static/js/usercss.js @@ -0,0 +1,57 @@ +/*global $, ace, Materialize, newCSS*/ +(function () { + var editor = ace.edit("css_editor"); + + function postForm() { + var name = $('#css_name').val(); + var css = editor.getValue(); + var funct = $.ajax({ + dataType: "json", + method: "POST", + data: {"name": name, "css": css} + }); + return funct.promise(); + } + + $(function(){ + editor.getSession().setMode("ace/mode/css"); + editor.setTheme("ace/theme/chrome"); + $("#submit-btn").click(submitForm); + + if (!newCSS) { + $("#delete-btn").click(delete_css); + } + }); + + function submitForm() { + var formPost = postForm(); + formPost.done(function (data) { + if (newCSS) { + window.location.href = "edit/" + data.id; + } else { + Materialize.toast('CSS Updated!', 10000); + } + }); + formPost.fail(function () { + Materialize.toast('Oh no! Something has failed posting your CSS!', 10000); + }); + } + + function delete_css() { + var candelete = confirm("Do you really want to delete this css???"); + if (!candelete) { + return; + } + + $.ajax({ + type: 'DELETE', + success: function() { + alert("You have successfully deleted the CSS!"); + window.location.href = "/user/dashboard"; + }, + error: function() { + Materialize.toast('Oh no! Something has failed deleting your CSS!', 10000); + } + }); + } +})(); \ No newline at end of file diff --git a/webapp/titanembeds/templates/dashboard.html.j2 b/webapp/titanembeds/templates/dashboard.html.j2 index 41d498e..06bc5fc 100644 --- a/webapp/titanembeds/templates/dashboard.html.j2 +++ b/webapp/titanembeds/templates/dashboard.html.j2 @@ -29,4 +29,35 @@ {% endfor %} + +
+ +{% if cosmetics is none %} +
+
+
+

Cosmetics!

+

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

+ Talk to us! +
+
+
+{% endif %} + +{% if css_list is not none %} +

+ Create or modify your custom CSS. + New +

+
+ {% for css in css_list %} +
+
+

#{{ css.id }} {{ css.name }}

+ Modify +
+
+ {% endfor %} +
+{% endif %} {% endblock %} diff --git a/webapp/titanembeds/templates/embed.html.j2 b/webapp/titanembeds/templates/embed.html.j2 index 3e85eea..fb5b664 100644 --- a/webapp/titanembeds/templates/embed.html.j2 +++ b/webapp/titanembeds/templates/embed.html.j2 @@ -14,6 +14,10 @@ {{ guild['name'] }} - Embed - Titan Embeds for Discord {% include 'google_analytics.html.j2' %} + + {% if css is not none %} + + {% endif %}