mirror of
https://github.com/zulip/zulip.git
synced 2025-11-09 16:37:23 +00:00
Add custom realm emoji UI to administration page.
This commit is contained in:
committed by
Tim Abbott
parent
f5fe2d4bf7
commit
f5e6176aea
@@ -68,6 +68,29 @@ casper.waitForSelector('.user_row[id="user_new-user-bot@zulip.com"]:not(.deactiv
|
||||
casper.test.assertSelectorHasText('.user_row[id="user_new-user-bot@zulip.com"]', 'Deactivate');
|
||||
});
|
||||
|
||||
// Test custom realm emoji
|
||||
casper.waitForSelector('.admin-emoji-form', function () {
|
||||
casper.fill('form.admin-emoji-form', {
|
||||
'name': 'MouseFace',
|
||||
'url': 'http://localhost:9991/static/images/integrations/logos/jenkins.png'
|
||||
});
|
||||
casper.click('form.admin-emoji-form input.btn');
|
||||
});
|
||||
|
||||
casper.waitUntilVisible('div#admin-emoji-status', function () {
|
||||
casper.test.assertSelectorHasText('div#admin-emoji-status', 'Custom emoji added!');
|
||||
});
|
||||
|
||||
casper.waitForSelector('.emoji_row', function () {
|
||||
casper.test.assertSelectorHasText('.emoji_row .emoji_name', 'MouseFace');
|
||||
casper.test.assertExists('.emoji_row img[src="http://localhost:9991/static/images/integrations/logos/jenkins.png"]');
|
||||
casper.click('.emoji_row button.delete');
|
||||
});
|
||||
|
||||
casper.waitWhileSelector('.emoji_row', function () {
|
||||
casper.test.assertDoesntExist('.emoji_row');
|
||||
});
|
||||
|
||||
// TODO: Test stream deletion
|
||||
|
||||
common.then_log_out();
|
||||
|
||||
@@ -728,6 +728,29 @@ function render(template_name, args) {
|
||||
|
||||
}());
|
||||
|
||||
(function admin_emoji_list() {
|
||||
global.use_template('admin_emoji_list');
|
||||
var args = {
|
||||
emoji: {
|
||||
"name": "MouseFace",
|
||||
"url": "http://emojipedia-us.s3.amazonaws.com/cache/46/7f/467fe69069c408e07517621f263ea9b5.png"
|
||||
}
|
||||
};
|
||||
|
||||
var html = '';
|
||||
html += '<tbody id="admin_emoji_table">';
|
||||
html += render('admin_emoji_list', args);
|
||||
html += '</tbody>';
|
||||
|
||||
global.write_test_output('admin_emoji_list.handlebars', html);
|
||||
|
||||
var emoji_name = $(html).find('tr.emoji_row:first span.emoji_name');
|
||||
var emoji_url = $(html).find('tr.emoji_row:first span.emoji_image img');
|
||||
|
||||
assert.equal(emoji_name.text(), 'MouseFace');
|
||||
assert.equal(emoji_url.attr('src'), 'http://emojipedia-us.s3.amazonaws.com/cache/46/7f/467fe69069c408e07517621f263ea9b5.png');
|
||||
}());
|
||||
|
||||
// By the end of this test, we should have compiled all our templates. Ideally,
|
||||
// we will also have exercised them to some degree, but that's a little trickier
|
||||
// to enforce.
|
||||
|
||||
@@ -20,6 +20,10 @@ function failed_listing_streams(xhr, error) {
|
||||
ui.report_error("Error listing streams", xhr, $("#administration-status"));
|
||||
}
|
||||
|
||||
function failed_listing_emoji(xhr, error) {
|
||||
ui.report_error("Error listing emoji", xhr, $("#administration-status"));
|
||||
}
|
||||
|
||||
function populate_users (realm_people_data) {
|
||||
var users_table = $("#admin_users_table");
|
||||
var deactivated_users_table = $("#admin_deactivated_users_table");
|
||||
@@ -70,6 +74,15 @@ function populate_streams (streams_data) {
|
||||
loading.destroy_indicator($('#admin_page_streams_loading_indicator'));
|
||||
}
|
||||
|
||||
function populate_emoji(emoji_data) {
|
||||
var emoji_table = $('#admin_emoji_table').expectOne();
|
||||
emoji_table.find('tr.emoji_row').remove();
|
||||
_.each(emoji_data, function (url, name) {
|
||||
emoji_table.append(templates.render('admin_emoji_list', {emoji: {name: name, url: url}}));
|
||||
});
|
||||
loading.destroy_indicator($('#admin_page_emoji_loading_indicator'));
|
||||
}
|
||||
|
||||
exports.setup_page = function () {
|
||||
var options = {
|
||||
realm_name: page_params.realm_name,
|
||||
@@ -85,12 +98,16 @@ exports.setup_page = function () {
|
||||
$("#admin-realm-restricted-to-domain-status").expectOne().hide();
|
||||
$("#admin-realm-invite-required-status").expectOne().hide();
|
||||
$("#admin-realm-invite-by-admins-only-status").expectOne().hide();
|
||||
$("#admin-emoji-status").expectOne().hide();
|
||||
$("#admin-emoji-name-status").expectOne().hide();
|
||||
$("#admin-emoji-url-status").expectOne().hide();
|
||||
|
||||
// create loading indicators
|
||||
loading.make_indicator($('#admin_page_users_loading_indicator'));
|
||||
loading.make_indicator($('#admin_page_bots_loading_indicator'));
|
||||
loading.make_indicator($('#admin_page_streams_loading_indicator'));
|
||||
loading.make_indicator($('#admin_page_deactivated_users_loading_indicator'));
|
||||
loading.make_indicator($('#admin_page_emoji_loading_indicator'));
|
||||
|
||||
// Populate users and bots tables
|
||||
channel.get({
|
||||
@@ -110,6 +127,9 @@ exports.setup_page = function () {
|
||||
error: failed_listing_streams
|
||||
});
|
||||
|
||||
// Populate emoji table
|
||||
populate_emoji(page_params.realm_emoji);
|
||||
|
||||
// Setup click handlers
|
||||
$(".admin_user_table").on("click", ".deactivate", function (e) {
|
||||
e.preventDefault();
|
||||
@@ -408,6 +428,67 @@ exports.setup_page = function () {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('.admin_emoji_table').on('click', '.delete', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var btn = $(this);
|
||||
|
||||
channel.del({
|
||||
url: '/json/realm/emoji/' + encodeURIComponent(btn.attr('data-emoji-name')),
|
||||
error: function (xhr, error_type) {
|
||||
if (xhr.status.toString().charAt(0) === "4") {
|
||||
btn.closest("td").html(
|
||||
$("<p>").addClass("text-error").text($.parseJSON(xhr.responseText).msg)
|
||||
);
|
||||
} else {
|
||||
btn.text("Failed!");
|
||||
}
|
||||
},
|
||||
success: function () {
|
||||
var row = btn.parents('tr');
|
||||
row.remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(".administration").on("submit", "form.admin-emoji-form", function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var emoji_status = $('#admin-emoji-status');
|
||||
var emoji_name_status = $('#admin-emoji-name-status');
|
||||
var emoji_url_status = $('#admin-emoji-url-status');
|
||||
var emoji_table = $('.admin_emoji_table');
|
||||
var emoji = {};
|
||||
$(this).serializeArray().map(function (x){emoji[x.name] = x.value;});
|
||||
|
||||
channel.put({
|
||||
url: "/json/realm/emoji",
|
||||
data: $(this).serialize(),
|
||||
success: function () {
|
||||
$('#admin-emoji-status, #admin-emoji-name-status, #admin-emoji-url-status').hide();
|
||||
emoji_table.append(templates.render("admin_emoji_list", {emoji: emoji}));
|
||||
ui.report_success("Custom emoji added!", emoji_status);
|
||||
},
|
||||
error: function (xhr, error) {
|
||||
$('#admin-emoji-status, #admin-emoji-name-status, #admin-emoji-url-status').hide();
|
||||
var errors = $.parseJSON(xhr.responseText).msg;
|
||||
if (errors.name !== undefined) {
|
||||
xhr.responseText = JSON.stringify({msg: errors.name});
|
||||
ui.report_error("Failed!", xhr, emoji_name_status);
|
||||
}
|
||||
if (errors.img_url !== undefined) {
|
||||
xhr.responseText = JSON.stringify({msg: errors.img_url});
|
||||
ui.report_error("Failed!", xhr, emoji_url_status);
|
||||
}
|
||||
if (errors.__all__ !== undefined) {
|
||||
xhr.responseText = JSON.stringify({msg: errors.__all__});
|
||||
ui.report_error("Failed!", xhr, emoji_status);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
return exports;
|
||||
|
||||
@@ -3220,7 +3220,8 @@ div.edit_bot {
|
||||
}
|
||||
|
||||
.edit_bot_form .control-label,
|
||||
#create_bot_form .control-label {
|
||||
#create_bot_form .control-label,
|
||||
.admin-emoji-form .control-label {
|
||||
width: 10em;
|
||||
text-align: right;
|
||||
margin-right: 20px;
|
||||
@@ -3380,11 +3381,13 @@ div.edit_bot {
|
||||
|
||||
#administration .settings-section .admin-realm-form,
|
||||
#settings .settings-section .new-bot-form,
|
||||
#emoji-settings .new-emoji-form,
|
||||
#settings .settings-section .edit-bot-form-box {
|
||||
margin-top: 35px;
|
||||
}
|
||||
|
||||
#settings .settings-section .new-bot-section-title {
|
||||
#settings .settings-section .new-bot-section-title,
|
||||
#emoji-settings .new-emoji-section-title {
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
}
|
||||
@@ -3397,12 +3400,14 @@ div.edit_bot {
|
||||
|
||||
#settings .settings-section .account-settings-form .control-label,
|
||||
#settings .settings-section .new-bot-form .control-label,
|
||||
#emoji-settings .new-emoji-form .control-label,
|
||||
#settings .settings-section .edit-bot-form-box .control-label {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
#settings .settings-section .account-settings-form .controls,
|
||||
#settings .settings-section .new-bot-form .controls,
|
||||
#emoji-settings .new-emoji-form .controls,
|
||||
#settings .settings-section .edit-bot-form-box .controls {
|
||||
margin-left: 140px;
|
||||
}
|
||||
@@ -3470,7 +3475,8 @@ div.edit_bot {
|
||||
}
|
||||
|
||||
#settings .bot-information-box,
|
||||
#settings .add-new-bot-box {
|
||||
#settings .add-new-bot-box,
|
||||
#emoji-settings .add-new-emoji-box {
|
||||
background: #e3e3e3;
|
||||
padding: 10px;
|
||||
margin-left: 38px;
|
||||
@@ -3481,7 +3487,8 @@ div.edit_bot {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#settings .add-new-bot-box {
|
||||
#settings .add-new-bot-box,
|
||||
#emoji-settings .add-new-emoji-box {
|
||||
background: #cbe3cb;
|
||||
}
|
||||
|
||||
@@ -3531,6 +3538,7 @@ div.edit_bot {
|
||||
|
||||
|
||||
#settings .settings-section .new-bot-form .control-label,
|
||||
#emoji-settings .new-emoji-form .control-label,
|
||||
#settings .settings-section .edit-bot-form-box .control-label {
|
||||
float: left;
|
||||
width: 120px;
|
||||
@@ -3538,7 +3546,8 @@ div.edit_bot {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#settings .settings-section .new-bot-form .controls {
|
||||
#settings .settings-section .new-bot-form .controls,
|
||||
#emoji-settings .new-emoji-form .controls {
|
||||
margin-left: 110px;
|
||||
}
|
||||
|
||||
@@ -3553,6 +3562,7 @@ div.edit_bot {
|
||||
#administration .settings-section .organization-settings .admin-realm-form,
|
||||
#settings .settings-section .account-settings-form,
|
||||
#settings .settings-section .new-bot-form,
|
||||
#emoji-settings .new-emoji-form,
|
||||
#settings .settings-section .notification-settings-form,
|
||||
#settings .settings-section .display-settings-form,
|
||||
#settings .settings-section .edit-bot-form-box {
|
||||
@@ -3562,6 +3572,7 @@ div.edit_bot {
|
||||
#administration .settings-section .admin-realm-form .control-label,
|
||||
#settings .settings-section .account-settings-form .control-label,
|
||||
#settings .settings-section .new-bot-form .control-label,
|
||||
#emoji-settings .new-emoji-form .control-label,
|
||||
#settings .settings-section .edit-bot-form-box .control-label {
|
||||
display: block;
|
||||
width: 120px;
|
||||
@@ -3575,6 +3586,7 @@ div.edit_bot {
|
||||
#administration .settings-section .admin-realm-form .controls,
|
||||
#settings .settings-section .account-settings-form .controls,
|
||||
#settings .settings-section .new-bot-form .controls,
|
||||
#emoji-settings .new-emoji-form .controls,
|
||||
#settings .settings-section .edit-bot-form-box .controls {
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
@@ -3585,13 +3597,16 @@ div.edit_bot {
|
||||
#settings .settings-section .account-settings-form .controls button,
|
||||
#settings .settings-section .account-settings-form .controls input,
|
||||
#settings .settings-section .new-bot-form .controls button,
|
||||
#emoji-settings .new-emoji-form .controls button,
|
||||
#settings .settings-section .edit-bot-form-box .controls button,
|
||||
#settings .settings-section .new-bot-form .controls input,
|
||||
#emoji-settings .new-emoji-form .controls input,
|
||||
#settings .settings-section .edit-bot-form-box .controls input {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#settings .settings-section .new-bot-form {
|
||||
#settings .settings-section .new-bot-form,
|
||||
#emoji-settings .new-emoji-form {
|
||||
padding: 0px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
@@ -4217,3 +4232,26 @@ li.show-more-private-messages a {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.admin_emoji_table {
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.emoji_image {
|
||||
width: 50px; display: block;
|
||||
}
|
||||
.emoji_image img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#admin-emoji-name-status, #admin-emoji-url-status {
|
||||
margin: 20px 0 0 0;
|
||||
}
|
||||
|
||||
.admin-table-wrapper {
|
||||
margin: 0 38px;
|
||||
}
|
||||
|
||||
#emoji-settings .new-emoji-form #emoji_url {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
15
static/templates/admin_emoji_list.handlebars
Normal file
15
static/templates/admin_emoji_list.handlebars
Normal file
@@ -0,0 +1,15 @@
|
||||
{{#with emoji}}
|
||||
<tr class="emoji_row" id="emoji_{{name}}">
|
||||
<td>
|
||||
<span class="emoji_name">{{name}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="emoji_image"><img src="{{url}}" alt="{{name}}" /></span>
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn delete btn-danger" data-emoji-name="{{name}}">
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{/with}}
|
||||
@@ -60,6 +60,42 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div id="emoji-settings" class="settings-section">
|
||||
<div class="settings-section-title"><i class="icon-vector-smile settings-section-icon"></i>
|
||||
Custom realm emoji</div>
|
||||
<div class="admin-table-wrapper">
|
||||
<table class="table table-condensed table-striped admin_emoji_table">
|
||||
<tbody id="admin_emoji_table">
|
||||
<th>Name</th>
|
||||
<th class="image">Image</th>
|
||||
<th class="actions">Actions</th>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<form class="form-horizontal admin-emoji-form">
|
||||
<div class="add-new-emoji-box">
|
||||
<div class="new-emoji-form">
|
||||
<div class="settings-section-title new-emoji-section-title">Add a New Emoji</div>
|
||||
<div class="alert" id="admin-emoji-status"></div>
|
||||
<div class="control-group">
|
||||
<label for="emoji_name" class="control-label">Emoji name</label>
|
||||
<input type="text" name="name" id="emoji_name" placeholder="mouse_face" />
|
||||
<div class="alert" id="admin-emoji-name-status"></div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label for="emoji_url" class="control-label">Emoji URL</label>
|
||||
<input type="text" name="url" id="emoji_url" placeholder="http://emojipedia-us.s3.amazonaws.com/cache/46/7f/467fe69069c408e07517621f263ea9b5.png" />
|
||||
<div class="alert" id="admin-emoji-url-status"></div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<input type="submit" class="btn btn-big btn-primary" value="Add emoji" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="users">
|
||||
<div id="admin-user-list" class="settings-section">
|
||||
|
||||
@@ -2890,8 +2890,10 @@ def notify_realm_emoji(realm):
|
||||
user_ids = [userdict['id'] for userdict in get_active_user_dicts_in_realm(realm)]
|
||||
send_event(event, user_ids)
|
||||
|
||||
def do_add_realm_emoji(realm, name, img_url):
|
||||
RealmEmoji(realm=realm, name=name, img_url=img_url).save()
|
||||
def check_add_realm_emoji(realm, name, img_url):
|
||||
emoji = RealmEmoji(realm=realm, name=name, img_url=img_url)
|
||||
emoji.full_clean()
|
||||
emoji.save()
|
||||
notify_realm_emoji(realm)
|
||||
|
||||
def do_remove_realm_emoji(realm, name):
|
||||
|
||||
@@ -3,7 +3,7 @@ from __future__ import print_function
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from zerver.models import Realm, get_realm
|
||||
from zerver.lib.actions import do_add_realm_emoji, do_remove_realm_emoji
|
||||
from zerver.lib.actions import check_add_realm_emoji, do_remove_realm_emoji
|
||||
import sys
|
||||
import six
|
||||
|
||||
@@ -48,7 +48,7 @@ Example: python2.7 manage.py realm_emoji --realm=zulip.com --op=show
|
||||
if img_url is None:
|
||||
self.print_help("python2.7 manage.py", "realm_emoji")
|
||||
sys.exit(1)
|
||||
do_add_realm_emoji(realm, name, img_url)
|
||||
check_add_realm_emoji(realm, name, img_url)
|
||||
sys.exit(0)
|
||||
elif options["op"] == "remove":
|
||||
do_remove_realm_emoji(realm, name)
|
||||
|
||||
25
zerver/migrations/0013_realmemoji.py
Normal file
25
zerver/migrations/0013_realmemoji.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import django.core.validators
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('zerver', '0012_remove_appledevicetoken'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='realmemoji',
|
||||
name='img_url',
|
||||
field=models.URLField(),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='realmemoji',
|
||||
name='name',
|
||||
field=models.TextField(validators=[django.core.validators.MinLengthValidator(1), django.core.validators.RegexValidator(regex=b'^[0-9a-zA-Z.\\-_]+(?<![.\\-_])$')]),
|
||||
),
|
||||
]
|
||||
@@ -13,12 +13,13 @@ from zerver.lib.cache import cache_with_key, flush_user_profile, flush_realm, \
|
||||
get_stream_cache_key, active_user_dicts_in_realm_cache_key, \
|
||||
active_bot_dicts_in_realm_cache_key
|
||||
from zerver.lib.utils import make_safe_digest, generate_random_token
|
||||
from django.db import transaction, IntegrityError
|
||||
from django.db import transaction
|
||||
from zerver.lib.avatar import gravatar_hash, get_avatar_url
|
||||
from django.utils import timezone
|
||||
from django.contrib.sessions.models import Session
|
||||
from zerver.lib.timestamp import datetime_to_timestamp
|
||||
from django.db.models.signals import pre_save, post_save, post_delete
|
||||
from django.core.validators import MinLengthValidator, RegexValidator
|
||||
import zlib
|
||||
|
||||
from bitfield import BitField
|
||||
@@ -214,8 +215,10 @@ def remote_user_to_email(remote_user):
|
||||
|
||||
class RealmEmoji(models.Model):
|
||||
realm = models.ForeignKey(Realm)
|
||||
name = models.TextField()
|
||||
img_url = models.TextField()
|
||||
# Second part of the regex (negative lookbehind) disallows names ending with one of the punctuation characters
|
||||
name = models.TextField(validators=[MinLengthValidator(1),
|
||||
RegexValidator(regex=r'^[0-9a-zA-Z.\-_]+(?<![.\-_])$')])
|
||||
img_url = models.URLField()
|
||||
|
||||
class Meta(object):
|
||||
unique_together = ("realm", "name")
|
||||
|
||||
@@ -6,7 +6,7 @@ from django.test import TestCase
|
||||
|
||||
from zerver.lib import bugdown
|
||||
from zerver.lib.actions import (
|
||||
do_add_realm_emoji,
|
||||
check_add_realm_emoji,
|
||||
do_remove_realm_emoji,
|
||||
get_realm,
|
||||
)
|
||||
@@ -307,7 +307,7 @@ class BugdownTest(TestCase):
|
||||
|
||||
zulip_realm = get_realm('zulip.com')
|
||||
url = "https://zulip.com/test_realm_emoji.png"
|
||||
do_add_realm_emoji(zulip_realm, "test", url)
|
||||
check_add_realm_emoji(zulip_realm, "test", url)
|
||||
|
||||
# Needs to mock an actual message because that's how bugdown obtains the realm
|
||||
msg = Message(sender=get_user_profile_by_email("hamlet@zulip.com"))
|
||||
|
||||
@@ -11,7 +11,7 @@ from zerver.lib.actions import (
|
||||
apply_events,
|
||||
create_stream_if_needed,
|
||||
do_add_alert_words,
|
||||
do_add_realm_emoji,
|
||||
check_add_realm_emoji,
|
||||
do_add_realm_filter,
|
||||
do_change_avatar_source,
|
||||
do_change_default_all_public_streams,
|
||||
@@ -479,7 +479,7 @@ class EventsRegisterTest(AuthedTestCase):
|
||||
('op', equals('update')),
|
||||
('realm_emoji', check_dict([])),
|
||||
])
|
||||
events = self.do_test(lambda: do_add_realm_emoji(get_realm("zulip.com"), "my_emoji",
|
||||
events = self.do_test(lambda: check_add_realm_emoji(get_realm("zulip.com"), "my_emoji",
|
||||
"https://realm.com/my_emoji"))
|
||||
error = schema_checker('events[0]', events[0])
|
||||
self.assert_on_error(error)
|
||||
|
||||
25
zerver/views/realm_emoji.py
Normal file
25
zerver/views/realm_emoji.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from zerver.lib.response import json_success, json_error
|
||||
from zerver.lib.actions import check_add_realm_emoji, do_remove_realm_emoji
|
||||
|
||||
from zerver.lib.rest import rest_dispatch as _rest_dispatch
|
||||
rest_dispatch = csrf_exempt((lambda request, *args, **kwargs: _rest_dispatch(request, globals(), *args, **kwargs)))
|
||||
|
||||
|
||||
def list_emoji(request, user_profile):
|
||||
return json_success({'emoji': user_profile.realm.get_emoji()})
|
||||
|
||||
def upload_emoji(request, user_profile):
|
||||
emoji_name = request.POST.get('name', None)
|
||||
emoji_url = request.POST.get('url', None)
|
||||
try:
|
||||
check_add_realm_emoji(user_profile.realm, emoji_name, emoji_url)
|
||||
except ValidationError as e:
|
||||
return json_error(e.message_dict)
|
||||
return json_success()
|
||||
|
||||
def delete_emoji(request, user_profile, emoji_name):
|
||||
do_remove_realm_emoji(user_profile.realm, emoji_name)
|
||||
return json_success({})
|
||||
@@ -188,7 +188,12 @@ v1_api_and_json_patterns = patterns('zerver.views',
|
||||
|
||||
# Returns a 204, used by desktop app to verify connectivity status
|
||||
url(r'generate_204$', 'generate_204'),
|
||||
|
||||
) + patterns('zerver.views.realm_emoji',
|
||||
url(r'^realm/emoji$', 'rest_dispatch',
|
||||
{'GET': 'list_emoji',
|
||||
'PUT': 'upload_emoji'}),
|
||||
url(r'^realm/emoji/(?P<emoji_name>[0-9a-zA-Z.\-_]+(?<![.\-_]))$', 'rest_dispatch',
|
||||
{'DELETE': 'delete_emoji'}),
|
||||
) + patterns('zerver.views.users',
|
||||
url(r'^users$', 'rest_dispatch',
|
||||
{'GET': 'get_members_backend',
|
||||
|
||||
Reference in New Issue
Block a user