mirror of
				https://github.com/TitanEmbeds/Titan.git
				synced 2025-11-03 23:37:09 +01:00 
			
		
		
		
	Implement file uploading from the embeds
This commit is contained in:
		@@ -0,0 +1,28 @@
 | 
			
		||||
"""Add file upload column to guilds table
 | 
			
		||||
 | 
			
		||||
Revision ID: ce2b9c930a7a
 | 
			
		||||
Revises: 12267ce662e9
 | 
			
		||||
Create Date: 2018-08-16 21:20:09.103071
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
# revision identifiers, used by Alembic.
 | 
			
		||||
revision = 'ce2b9c930a7a'
 | 
			
		||||
down_revision = '12267ce662e9'
 | 
			
		||||
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('guilds', sa.Column('file_upload', sa.Boolean(), server_default='0', nullable=False))
 | 
			
		||||
    # ### end Alembic commands ###
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def downgrade():
 | 
			
		||||
    # ### commands auto generated by Alembic - please adjust! ###
 | 
			
		||||
    op.drop_column('guilds', 'file_upload')
 | 
			
		||||
    # ### end Alembic commands ###
 | 
			
		||||
@@ -32,6 +32,7 @@ app.config['SQLALCHEMY_POOL_SIZE'] = 15
 | 
			
		||||
app.config['RATELIMIT_STORAGE_URL'] = config["redis-uri"]
 | 
			
		||||
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=3)
 | 
			
		||||
app.config['REDIS_URL'] = config["redis-uri"]
 | 
			
		||||
app.config['MAX_CONTENT_LENGTH'] = 4 * 1024 * 1024 # Limit upload size to 4mb
 | 
			
		||||
app.secret_key = config['app-secret']
 | 
			
		||||
 | 
			
		||||
sentry.init_app(app)
 | 
			
		||||
 
 | 
			
		||||
@@ -193,7 +193,8 @@ def administrate_guild(guild_id):
 | 
			
		||||
        "banned_words_global_included": db_guild.banned_words_global_included,
 | 
			
		||||
        "banned_words": json.loads(db_guild.banned_words),
 | 
			
		||||
        "autorole_unauth": db_guild.autorole_unauth,
 | 
			
		||||
        "autorole_discord": db_guild.autorole_discord
 | 
			
		||||
        "autorole_discord": db_guild.autorole_discord,
 | 
			
		||||
        "file_upload": db_guild.file_upload,
 | 
			
		||||
    }
 | 
			
		||||
    return render_template("administrate_guild.html.j2", guild=dbguild_dict, members=users, permissions=permissions, cosmetics=cosmetics)
 | 
			
		||||
 | 
			
		||||
@@ -214,6 +215,7 @@ def update_administrate_guild(guild_id):
 | 
			
		||||
    db_guild.banned_words_global_included = request.form.get("banned_words_global_included", db_guild.banned_words_global_included) in ["true", True]
 | 
			
		||||
    db_guild.autorole_unauth = request.form.get("autorole_unauth", db_guild.autorole_unauth, type=int)
 | 
			
		||||
    db_guild.autorole_discord = request.form.get("autorole_discord", db_guild.autorole_discord, type=int)
 | 
			
		||||
    db_guild.file_upload = request.form.get("file_upload", db_guild.file_upload) in ["true", True]
 | 
			
		||||
    invite_link = request.form.get("invite_link", db_guild.invite_link)
 | 
			
		||||
    if invite_link != None and invite_link.strip() == "":
 | 
			
		||||
        invite_link = None
 | 
			
		||||
@@ -250,7 +252,8 @@ def update_administrate_guild(guild_id):
 | 
			
		||||
        banned_words_global_included=db_guild.banned_words_global_included,
 | 
			
		||||
        banned_words=json.loads(db_guild.banned_words),
 | 
			
		||||
        autorole_unauth=db_guild.autorole_unauth,
 | 
			
		||||
        autorole_discord=db_guild.autorole_discord
 | 
			
		||||
        autorole_discord=db_guild.autorole_discord,
 | 
			
		||||
        file_upload=db_guild.file_upload,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
@admin.route("/guilds")
 | 
			
		||||
 
 | 
			
		||||
@@ -273,7 +273,12 @@ def get_post_content_max_len(guild_id):
 | 
			
		||||
def post():
 | 
			
		||||
    guild_id = request.form.get("guild_id")
 | 
			
		||||
    channel_id = request.form.get('channel_id')
 | 
			
		||||
    content = request.form.get('content')
 | 
			
		||||
    content = request.form.get('content', "")
 | 
			
		||||
    file = None
 | 
			
		||||
    if "file" in request.files:
 | 
			
		||||
        file = request.files["file"]
 | 
			
		||||
    if file and file.filename == "":
 | 
			
		||||
        file = None
 | 
			
		||||
    if "user_id" in session:
 | 
			
		||||
        dbUser = redisqueue.get_guild_member(guild_id, session["user_id"])
 | 
			
		||||
    else:
 | 
			
		||||
@@ -293,6 +298,8 @@ def post():
 | 
			
		||||
        chan = filter_guild_channel(guild_id, channel_id)
 | 
			
		||||
        if not chan.get("write") or chan["channel"]["type"] != "text":
 | 
			
		||||
            status_code = 401
 | 
			
		||||
        elif file and not chan.get("attach_files"):
 | 
			
		||||
            status_code = 406
 | 
			
		||||
        elif not illegal_post:
 | 
			
		||||
            userid = session["user_id"]
 | 
			
		||||
            content = format_everyone_mention(chan, content)
 | 
			
		||||
@@ -318,9 +325,9 @@ def post():
 | 
			
		||||
                    #     username = "(Titan Dev) " + username
 | 
			
		||||
                    username = username + "#" + str(session['discriminator'])
 | 
			
		||||
                    avatar = session['avatar']
 | 
			
		||||
                message = discord_api.execute_webhook(webhook.get("id"), webhook.get("token"), username, avatar, content)
 | 
			
		||||
                message = discord_api.execute_webhook(webhook.get("id"), webhook.get("token"), username, avatar, content, file)
 | 
			
		||||
            else:
 | 
			
		||||
                message = discord_api.create_message(channel_id, content)
 | 
			
		||||
                message = discord_api.create_message(channel_id, content, file)
 | 
			
		||||
            status_code = message['code']
 | 
			
		||||
    db.session.commit()
 | 
			
		||||
    response = jsonify(message=message.get('content', message), status=status, illegal_reasons=illegal_reasons)
 | 
			
		||||
 
 | 
			
		||||
@@ -230,7 +230,8 @@ def administrate_guild(guild_id):
 | 
			
		||||
        "banned_words_global_included": db_guild.banned_words_global_included,
 | 
			
		||||
        "banned_words": json.loads(db_guild.banned_words),
 | 
			
		||||
        "autorole_unauth": db_guild.autorole_unauth,
 | 
			
		||||
        "autorole_discord": db_guild.autorole_discord
 | 
			
		||||
        "autorole_discord": db_guild.autorole_discord,
 | 
			
		||||
        "file_upload": db_guild.file_upload,
 | 
			
		||||
    }
 | 
			
		||||
    return render_template("administrate_guild.html.j2", guild=dbguild_dict, members=users, permissions=permissions, cosmetics=cosmetics, disabled=(guild_id in list_disabled_guilds()))
 | 
			
		||||
 | 
			
		||||
@@ -259,6 +260,7 @@ def update_administrate_guild(guild_id):
 | 
			
		||||
    db_guild.banned_words_global_included = request.form.get("banned_words_global_included", db_guild.banned_words_global_included) in ["true", True]
 | 
			
		||||
    db_guild.autorole_unauth = request.form.get("autorole_unauth", db_guild.autorole_unauth, type=int)
 | 
			
		||||
    db_guild.autorole_discord = request.form.get("autorole_discord", db_guild.autorole_discord, type=int)
 | 
			
		||||
    db_guild.file_upload = request.form.get("file_upload", db_guild.file_upload) in ["true", True]
 | 
			
		||||
    
 | 
			
		||||
    invite_link = request.form.get("invite_link", db_guild.invite_link)
 | 
			
		||||
    if invite_link != None and invite_link.strip() == "":
 | 
			
		||||
@@ -299,7 +301,8 @@ def update_administrate_guild(guild_id):
 | 
			
		||||
        banned_words_global_included=db_guild.banned_words_global_included,
 | 
			
		||||
        banned_words=json.loads(db_guild.banned_words),
 | 
			
		||||
        autorole_unauth=db_guild.autorole_unauth,
 | 
			
		||||
        autorole_discord=db_guild.autorole_discord
 | 
			
		||||
        autorole_discord=db_guild.autorole_discord,
 | 
			
		||||
        file_upload=db_guild.file_upload,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
@user.route("/add-bot/<guild_id>")
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ class Guilds(db.Model):
 | 
			
		||||
    banned_words = db.Column(db.Text(), nullable=False, server_default="[]")    # JSON list of strings to block from sending
 | 
			
		||||
    autorole_unauth = db.Column(db.BigInteger, nullable=True, server_default=None) # Automatic Role inherit for unauthenticated users
 | 
			
		||||
    autorole_discord = db.Column(db.BigInteger, nullable=True, server_default=None) # Automatic Role inherit for discord users
 | 
			
		||||
    file_upload = db.Column(db.Boolean(), nullable=False, server_default="0")     # Allow file uploading for server
 | 
			
		||||
 | 
			
		||||
    def __init__(self, guild_id):
 | 
			
		||||
        self.guild_id = guild_id
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ import requests
 | 
			
		||||
import sys
 | 
			
		||||
import time
 | 
			
		||||
import json
 | 
			
		||||
import urllib
 | 
			
		||||
from titanembeds.utils import redis_store
 | 
			
		||||
from flask import request
 | 
			
		||||
 | 
			
		||||
@@ -61,7 +62,12 @@ class DiscordREST:
 | 
			
		||||
                time.sleep(int(self._get_bucket(url)) - curepoch)
 | 
			
		||||
 | 
			
		||||
            url_formatted = _DISCORD_API_BASE + url
 | 
			
		||||
            req = requests.request(verb, url_formatted, params=params, data=data, headers=headers)
 | 
			
		||||
            if data and "payload_json" in data:
 | 
			
		||||
                if "Content-Type" in headers:
 | 
			
		||||
                    del headers["Content-Type"]
 | 
			
		||||
                req = requests.request(verb, url_formatted, params=params, files=data, headers=headers)
 | 
			
		||||
            else:
 | 
			
		||||
                req = requests.request(verb, url_formatted, params=params, data=data, headers=headers)
 | 
			
		||||
 | 
			
		||||
            remaining = None
 | 
			
		||||
            if 'X-RateLimit-Remaining' in req.headers:
 | 
			
		||||
@@ -103,9 +109,11 @@ class DiscordREST:
 | 
			
		||||
    # Channel
 | 
			
		||||
    #####################
 | 
			
		||||
 | 
			
		||||
    def create_message(self, channel_id, content):
 | 
			
		||||
    def create_message(self, channel_id, content, file=None):
 | 
			
		||||
        _endpoint = "/channels/{channel_id}/messages".format(channel_id=channel_id)
 | 
			
		||||
        payload = {'content': content}
 | 
			
		||||
        if file:
 | 
			
		||||
            payload = {"payload_json": (None, json.dumps(payload)), "file": (file.filename, file.read(), 'application/octet-stream')}
 | 
			
		||||
        r = self.request("POST", _endpoint, data=payload)
 | 
			
		||||
        return r
 | 
			
		||||
 | 
			
		||||
@@ -164,7 +172,7 @@ class DiscordREST:
 | 
			
		||||
        r = self.request("POST", _endpoint, data=payload, json=True)
 | 
			
		||||
        return r
 | 
			
		||||
    
 | 
			
		||||
    def execute_webhook(self, webhook_id, webhook_token, username, avatar, content, wait=True):
 | 
			
		||||
    def execute_webhook(self, webhook_id, webhook_token, username, avatar, content, file=None, wait=True):
 | 
			
		||||
        _endpoint = "/webhooks/{id}/{token}".format(id=webhook_id, token=webhook_token)
 | 
			
		||||
        if wait:
 | 
			
		||||
            _endpoint += "?wait=true"
 | 
			
		||||
@@ -173,6 +181,8 @@ class DiscordREST:
 | 
			
		||||
            'avatar_url': avatar,
 | 
			
		||||
            'username': username
 | 
			
		||||
        }
 | 
			
		||||
        if file:
 | 
			
		||||
            payload = {"payload_json": (None, json.dumps(payload)), "file": (file.filename, file.read(), 'application/octet-stream')}
 | 
			
		||||
        r = self.request("POST", _endpoint, data=payload)
 | 
			
		||||
        return r
 | 
			
		||||
    
 | 
			
		||||
 
 | 
			
		||||
@@ -873,16 +873,65 @@ p.mentioned span.chatmessage {
 | 
			
		||||
  padding: 2px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media only screen and (max-device-width: 320px) {
 | 
			
		||||
@media only screen and (max-width: 320px) {
 | 
			
		||||
  .wdt-emoji-picker {
 | 
			
		||||
      display: none;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  #upload-file-btn {
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media only screen and (min-device-width: 321px) {
 | 
			
		||||
@media only screen and (min-width: 321px) {
 | 
			
		||||
  .wdt-emoji-picker {
 | 
			
		||||
      display: block;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  #upload-file-btn {
 | 
			
		||||
    display: block;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#upload-file-btn {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  bottom: 5px;
 | 
			
		||||
  right: 38px;
 | 
			
		||||
  color: gray;
 | 
			
		||||
  padding: 1px;
 | 
			
		||||
  transition: .3s ease-out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#upload-file-btn:hover {
 | 
			
		||||
  color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#fileinput {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media only screen and (min-width: 500px) {
 | 
			
		||||
  #filemodal-body {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: space-evenly;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  #filemodal-right {
 | 
			
		||||
    width: 75%;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#filepreview {
 | 
			
		||||
  max-width: 100px;
 | 
			
		||||
  max-height: 100px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#messagebox-filemodal {
 | 
			
		||||
  background-color: rgba(0, 0, 0, 0.07);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#messagebox-filemodal::placeholder {
 | 
			
		||||
  color: #90a4ae;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#mention-picker {
 | 
			
		||||
@@ -934,7 +983,7 @@ p.mentioned span.chatmessage {
 | 
			
		||||
  margin-left: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media only screen and (max-device-width: 320px) {
 | 
			
		||||
@media only screen and (max-width: 320px) {
 | 
			
		||||
  #mention-picker .realname {
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -173,6 +173,15 @@ $("#autorole_discord").change(function () {
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
$('#file_upload').change(function() {
 | 
			
		||||
    var pathname = window.location.pathname;
 | 
			
		||||
    var checked = $(this).is(':checked')
 | 
			
		||||
    var payload = {"file_upload": checked}
 | 
			
		||||
    $.post(pathname, payload, function(data) {
 | 
			
		||||
      Materialize.toast('Updated file uploads setting!', 2000)
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function initiate_ban(guild_id, user_id) {
 | 
			
		||||
  var reason = prompt("Please enter your reason for ban");
 | 
			
		||||
  var payload = {
 | 
			
		||||
 
 | 
			
		||||
@@ -137,13 +137,44 @@
 | 
			
		||||
        return funct.promise();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function post(channel_id, content) {
 | 
			
		||||
        var funct = $.ajax({
 | 
			
		||||
    function post(channel_id, content, file) {
 | 
			
		||||
        if (content == "") {
 | 
			
		||||
            content = null;
 | 
			
		||||
        }
 | 
			
		||||
        var data = null;
 | 
			
		||||
        var ajaxobj = {
 | 
			
		||||
            method: "POST",
 | 
			
		||||
            dataType: "json",
 | 
			
		||||
            url: "/api/post",
 | 
			
		||||
            data: {"guild_id": guild_id, "channel_id": channel_id, "content": content}
 | 
			
		||||
        });
 | 
			
		||||
            url: "/api/post"
 | 
			
		||||
        }
 | 
			
		||||
        if (file) {
 | 
			
		||||
            data = new FormData();
 | 
			
		||||
            data.append("guild_id", guild_id);
 | 
			
		||||
            data.append("channel_id", channel_id);
 | 
			
		||||
            if (content) {
 | 
			
		||||
                data.append("content", content);
 | 
			
		||||
            }
 | 
			
		||||
            data.append("file", file);
 | 
			
		||||
            ajaxobj.cache = false;
 | 
			
		||||
            ajaxobj.contentType = false;
 | 
			
		||||
            ajaxobj.processData = false;
 | 
			
		||||
            ajaxobj.xhr = function() {
 | 
			
		||||
                var myXhr = $.ajaxSettings.xhr();
 | 
			
		||||
                if (myXhr.upload) {
 | 
			
		||||
                    // For handling the progress of the upload
 | 
			
		||||
                    myXhr.upload.addEventListener('progress', function(e) {
 | 
			
		||||
                        if (e.lengthComputable) {
 | 
			
		||||
                            $("#filemodalprogress-inner").css("width", (e.loaded/e.total) + "%")
 | 
			
		||||
                        }
 | 
			
		||||
                    } , false);
 | 
			
		||||
                }
 | 
			
		||||
                return myXhr;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            data = {"guild_id": guild_id, "channel_id": channel_id, "content": content};
 | 
			
		||||
        }
 | 
			
		||||
        ajaxobj.data = data;
 | 
			
		||||
        var funct = $.ajax(ajaxobj);
 | 
			
		||||
        return funct.promise();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
@@ -214,6 +245,13 @@
 | 
			
		||||
            inDuration: 400,
 | 
			
		||||
            outDuration: 400,
 | 
			
		||||
        });
 | 
			
		||||
        $("#filemodal").modal({
 | 
			
		||||
            dismissible: true,
 | 
			
		||||
            opacity: .3,
 | 
			
		||||
            inDuration: 400,
 | 
			
		||||
            outDuration: 400,
 | 
			
		||||
            complete: function () { $("#fileinput").val(""); }
 | 
			
		||||
        });
 | 
			
		||||
        $("#usercard").modal({
 | 
			
		||||
            opacity: .5,
 | 
			
		||||
        });
 | 
			
		||||
@@ -237,6 +275,44 @@
 | 
			
		||||
            $("#nsfwmodal").modal("close");
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        $("#upload-file-btn").click(function () {
 | 
			
		||||
            $("#fileinput").trigger('click');
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        $("#proceed_fileupload_btn").click(function () {
 | 
			
		||||
            $("#messagebox-filemodal").trigger(jQuery.Event("keydown", { keyCode: 13 } ));
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        $("#fileinput").change(function (e){
 | 
			
		||||
            var files = e.target.files;
 | 
			
		||||
            if (files && files.length > 0) {
 | 
			
		||||
                $("#messagebox-filemodal").val($("#messagebox").val());
 | 
			
		||||
                $("#filename").text($("#fileinput")[0].files[0].name);
 | 
			
		||||
                $("#filemodal").modal("open");
 | 
			
		||||
                $("#messagebox-filemodal").focus();
 | 
			
		||||
                var file = files[0];
 | 
			
		||||
                var file_size = file.size;
 | 
			
		||||
                var file_max_size = 4 * 1024 * 1024;
 | 
			
		||||
                if (file_size > file_max_size) {
 | 
			
		||||
                    $("#filemodal").modal("close");
 | 
			
		||||
                    Materialize.toast('Your file is too powerful! The maximum file size is 4 megabytes.', 5000);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                var name = file.name;
 | 
			
		||||
                var extension = name.substr(-4).toLowerCase();
 | 
			
		||||
                var image_extensions = [".png", ".jpg", ".jpeg", ".gif"];
 | 
			
		||||
                $("#filepreview").hide();
 | 
			
		||||
                if (FileReader && image_extensions.indexOf(extension) > -1) {
 | 
			
		||||
                    var reader = new FileReader();
 | 
			
		||||
                    reader.onload = function() {
 | 
			
		||||
                        $("#filepreview").show();
 | 
			
		||||
                        $("#filepreview")[0].src = reader.result;
 | 
			
		||||
                    };
 | 
			
		||||
                    reader.readAsDataURL(file);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        $( "#theme-selector" ).change(function () {
 | 
			
		||||
            var theme = $("#theme-selector option:selected").val();
 | 
			
		||||
            var keep_custom_css = $("#overwrite_theme_custom_css_checkbox").is(':checked');
 | 
			
		||||
@@ -444,11 +520,13 @@
 | 
			
		||||
            $("#messagebox").hide();
 | 
			
		||||
            $("#emoji-tray-toggle").hide();
 | 
			
		||||
            $(".wdt-emoji-picker").hide();
 | 
			
		||||
            $("#upload-file-btn").hide();
 | 
			
		||||
        } else {
 | 
			
		||||
            $("#visitor_mode_message").hide();
 | 
			
		||||
            $("#messagebox").show();
 | 
			
		||||
            $("#emoji-tray-toggle").show();
 | 
			
		||||
            $(".wdt-emoji-picker").show();
 | 
			
		||||
            $("#upload-file-btn").show();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -658,6 +736,7 @@
 | 
			
		||||
            if (curr_default_channel == null) {
 | 
			
		||||
                $("#messagebox").prop('disabled', true);
 | 
			
		||||
                $("#messagebox").prop('placeholder', "NO TEXT CHANNELS");
 | 
			
		||||
                $("#upload-file-btn").hide();
 | 
			
		||||
                Materialize.toast("You find yourself in a strange place. You don't have access to any text channels, or there are none in this server.", 20000);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
@@ -667,9 +746,18 @@
 | 
			
		||||
        if (this_channel.write) {
 | 
			
		||||
            $("#messagebox").prop('disabled', false);
 | 
			
		||||
            $("#messagebox").prop('placeholder', "Enter message");
 | 
			
		||||
            $("#upload-file-btn").show();
 | 
			
		||||
            $(".wdt-emoji-picker").show();
 | 
			
		||||
        } else {
 | 
			
		||||
            $("#messagebox").prop('disabled', true);
 | 
			
		||||
            $("#messagebox").prop('placeholder', "Messages is disabled in this channel.");
 | 
			
		||||
            $("#upload-file-btn").hide();
 | 
			
		||||
            $(".wdt-emoji-picker").hide();
 | 
			
		||||
        }
 | 
			
		||||
        if (this_channel.attach_files) {
 | 
			
		||||
            $("#upload-file-btn").show();
 | 
			
		||||
        } else {
 | 
			
		||||
            $("#upload-file-btn").hide();
 | 
			
		||||
        }
 | 
			
		||||
        $("#channeltopic").text(this_channel.channel.topic);
 | 
			
		||||
        $("#channel-"+selected_channel).parent().addClass("active");
 | 
			
		||||
@@ -1744,9 +1832,11 @@
 | 
			
		||||
        if (event.keyCode == 16) {
 | 
			
		||||
            shift_pressed = true;
 | 
			
		||||
        }
 | 
			
		||||
        if(event.keyCode == 13 && !shift_pressed && $(this).val().length >= 1) {
 | 
			
		||||
        if(event.keyCode == 13 && !shift_pressed && ($(this).val().length >= 1 || $("#fileinput").val().length >= 1)) {
 | 
			
		||||
            $(this).val($.trim($(this).val()));
 | 
			
		||||
            $(this).blur();
 | 
			
		||||
            $("#messagebox-filemodal").attr('readonly', true);
 | 
			
		||||
            $("#proceed_fileupload_btn").attr("disabled", true);
 | 
			
		||||
            $("#messagebox").attr('readonly', true);
 | 
			
		||||
            var emojiConvertor = new EmojiConvertor();
 | 
			
		||||
            emojiConvertor.init_env();
 | 
			
		||||
@@ -1754,9 +1844,18 @@
 | 
			
		||||
            emojiConvertor.allow_native = true;
 | 
			
		||||
            var messageInput = emojiConvertor.replace_colons($(this).val());
 | 
			
		||||
            messageInput = stringToDefaultEmote(messageInput);
 | 
			
		||||
            var funct = post(selected_channel, messageInput);
 | 
			
		||||
            var file = null;
 | 
			
		||||
            if ($("#fileinput")[0].files.length > 0) {
 | 
			
		||||
                file = $("#fileinput")[0].files[0];
 | 
			
		||||
            }
 | 
			
		||||
            $("#filemodalprogress").show();
 | 
			
		||||
            var funct = post(selected_channel, messageInput, file);
 | 
			
		||||
            funct.done(function(data) {
 | 
			
		||||
                $("#messagebox").val("");
 | 
			
		||||
                $("#messagebox-filemodal").val("");
 | 
			
		||||
                $("#fileinput").val("");
 | 
			
		||||
                $("#filemodal").modal("close");
 | 
			
		||||
                $("#filemodalprogress").hide();
 | 
			
		||||
            });
 | 
			
		||||
            funct.fail(function(data) {
 | 
			
		||||
                Materialize.toast('Failed to send message.', 10000);
 | 
			
		||||
@@ -1773,10 +1872,38 @@
 | 
			
		||||
            });
 | 
			
		||||
            funct.always(function() {
 | 
			
		||||
                $("#messagebox").attr('readonly', false);
 | 
			
		||||
                $("#messagebox").focus();
 | 
			
		||||
                $("#messagebox-filemodal").attr('readonly', false);
 | 
			
		||||
                $("#proceed_fileupload_btn").attr("disabled", false);
 | 
			
		||||
                if ($("#filemodal").is(":visible")) {
 | 
			
		||||
                    $("#messagebox-filemodal").focus();
 | 
			
		||||
                } else {
 | 
			
		||||
                    $("#messagebox").focus();
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    $("#messagebox-filemodal").keyup(function (event) {
 | 
			
		||||
        if (event.keyCode == 16) {
 | 
			
		||||
            shift_pressed = false;
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    $("#messagebox-filemodal").keydown(function (event) {
 | 
			
		||||
        if ($(this).val().length == 1) {
 | 
			
		||||
            $(this).val($.trim($(this).val()));
 | 
			
		||||
        }
 | 
			
		||||
        if (event.keyCode == 16) {
 | 
			
		||||
            shift_pressed = true;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if(event.keyCode == 13 && !shift_pressed) {
 | 
			
		||||
            $(this).val($.trim($(this).val()));
 | 
			
		||||
            $(this).blur();
 | 
			
		||||
            $("#messagebox").val($(this).val());
 | 
			
		||||
            $("#messagebox").trigger(jQuery.Event("keydown", { keyCode: 13 } ));
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $('#guild-btn').sideNav({
 | 
			
		||||
        menuWidth: 300, // Default is 300
 | 
			
		||||
 
 | 
			
		||||
@@ -214,6 +214,19 @@
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <br>
 | 
			
		||||
            
 | 
			
		||||
            <p class="flow-text">Toggle File Attachments</p>
 | 
			
		||||
            <p>Allow embed users to attach files to your Discord server in messages</p>
 | 
			
		||||
            <div class="switch">
 | 
			
		||||
              <label>
 | 
			
		||||
                Disable
 | 
			
		||||
                <input type="checkbox" id="file_upload" name="file_upload" {% if guild['file_upload'] %}checked{% endif %}  >
 | 
			
		||||
                <span class="lever"></span>
 | 
			
		||||
                Enable
 | 
			
		||||
              </label>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -79,6 +79,7 @@
 | 
			
		||||
          <div id="messageboxouter" class="input-field inline">
 | 
			
		||||
            <textarea placeholder="Enter message" id="messagebox" type="text" class="materialize-textarea wdt-emoji-open-on-colon" rows="1"></textarea>
 | 
			
		||||
            <span id="visitor_mode_message" style="display:none;"><span id="visitor_mode_message_note">{{ _("Please login to post a message.") }}</span> <a id="visitor_login_btn" class="waves-effect waves-light btn">{{ _("Login") }}</a></span>
 | 
			
		||||
            <a id="upload-file-btn" class="btn-flat"><i class="material-icons">file_upload</i></a>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </footer>
 | 
			
		||||
@@ -243,6 +244,31 @@
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
    <div id="filemodal" class="modal">
 | 
			
		||||
      <div class="modal-content">
 | 
			
		||||
        <h4 class="center-align">{{ _("Attach File") }}</h4>
 | 
			
		||||
        <h5 id="filename" class="center-align"></h5>
 | 
			
		||||
        <div id="filemodalprogress" class="progress" style="display: none;">
 | 
			
		||||
          <div id="filemodalprogress-inner" class="determinate"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div id="filemodal-body">
 | 
			
		||||
          <div id="filemodal-left" class="valign-wrapper">
 | 
			
		||||
            <img id="filepreview" class="responsive-img" src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png">
 | 
			
		||||
          </div>
 | 
			
		||||
          <div id="filemodal-right">
 | 
			
		||||
            <p>{{ _("Add a comment (optional)") }}</p>
 | 
			
		||||
            <p class="center-align">
 | 
			
		||||
              <textarea placeholder="Enter message" id="messagebox-filemodal" type="text" class="materialize-textarea" rows="1"></textarea>
 | 
			
		||||
            </p>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <p class="right-align">
 | 
			
		||||
          <a id="proceed_fileupload_btn" class="waves-effect waves-light btn">{{ _("Upload") }}</a>
 | 
			
		||||
        </p>
 | 
			
		||||
        <input type="file" id="fileinput">
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
    <div id="usercard" class="modal bottom-sheet">
 | 
			
		||||
      <div class="modal-content">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
 
 | 
			
		||||
@@ -214,6 +214,7 @@ def get_guild_channels(guild_id, force_everyone=False, forced_role=0):
 | 
			
		||||
    if guild_id not in bot_member_roles:
 | 
			
		||||
        bot_member_roles.append(guild_id)
 | 
			
		||||
    guild = redisqueue.get_guild(guild_id)
 | 
			
		||||
    db_guild = db.session.query(Guilds).filter(Guilds.guild_id == guild_id).first()
 | 
			
		||||
    guild_channels = guild["channels"]
 | 
			
		||||
    guild_roles = guild["roles"]
 | 
			
		||||
    guild_owner = guild["owner_id"]
 | 
			
		||||
@@ -228,17 +229,20 @@ def get_guild_channels(guild_id, force_everyone=False, forced_role=0):
 | 
			
		||||
                result["write"] = False
 | 
			
		||||
            if not bot_result["mention_everyone"]:
 | 
			
		||||
                result["mention_everyone"] = False
 | 
			
		||||
            if not bot_result["attach_files"] or not db_guild.file_upload:
 | 
			
		||||
                result["attach_files"] = False
 | 
			
		||||
            result_channels.append(result)
 | 
			
		||||
    return sorted(result_channels, key=lambda k: k['channel']['position'])
 | 
			
		||||
 | 
			
		||||
def get_channel_permission(channel, guild_id, guild_owner, guild_roles, member_roles, user_id=None, force_everyone=False):
 | 
			
		||||
    result = {"channel": channel, "read": False, "write": False, "mention_everyone": False}
 | 
			
		||||
    result = {"channel": channel, "read": False, "write": False, "mention_everyone": False, "attach_files": False}
 | 
			
		||||
    if not user_id:
 | 
			
		||||
        user_id = str(session.get("user_id"))
 | 
			
		||||
    if guild_owner == user_id:
 | 
			
		||||
        result["read"] = True
 | 
			
		||||
        result["write"] = True
 | 
			
		||||
        result["mention_everyone"] = True
 | 
			
		||||
        result["attach_files"] = True
 | 
			
		||||
        return result
 | 
			
		||||
    channel_perm = 0
 | 
			
		||||
    
 | 
			
		||||
@@ -265,6 +269,7 @@ def get_channel_permission(channel, guild_id, guild_owner, guild_roles, member_r
 | 
			
		||||
        result["read"] = True
 | 
			
		||||
        result["write"] = True
 | 
			
		||||
        result["mention_everyone"] = True
 | 
			
		||||
        result["attach_files"] = True
 | 
			
		||||
        return result
 | 
			
		||||
    
 | 
			
		||||
    denies = 0
 | 
			
		||||
@@ -287,16 +292,14 @@ def get_channel_permission(channel, guild_id, guild_owner, guild_roles, member_r
 | 
			
		||||
    result["read"] = user_has_permission(channel_perm, 10)
 | 
			
		||||
    result["write"] = user_has_permission(channel_perm, 11)
 | 
			
		||||
    result["mention_everyone"] = user_has_permission(channel_perm, 17)
 | 
			
		||||
    
 | 
			
		||||
    # If default channel, you can read
 | 
			
		||||
    if channel["id"] == guild_id:
 | 
			
		||||
        result["read"] = True
 | 
			
		||||
    result["attach_files"] = user_has_permission(channel_perm, 15)
 | 
			
		||||
    
 | 
			
		||||
    # If you cant read channel, you cant write in it
 | 
			
		||||
    if not user_has_permission(channel_perm, 10):
 | 
			
		||||
        result["read"] = False
 | 
			
		||||
        result["write"] = False
 | 
			
		||||
        result["mention_everyone"] = False
 | 
			
		||||
        result["attach_files"] = False
 | 
			
		||||
    return result
 | 
			
		||||
    
 | 
			
		||||
def get_forced_role(guild_id):
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user