Sorted online discord server members by roles and color. fixed caching a bit

This commit is contained in:
Jeremy Zhang 2017-04-13 23:10:13 -07:00
parent 789341ace9
commit b040f614c2
5 changed files with 147 additions and 50 deletions

View File

@ -186,7 +186,7 @@ def get_guild_channels(guild_id):
result["read"] = False result["read"] = False
result["write"] = False result["write"] = False
#if result["read"]: if result["read"]:
result_channels.append(result) result_channels.append(result)
return sorted(result_channels, key=lambda k: k['channel']['position']) return sorted(result_channels, key=lambda k: k['channel']['position'])
@ -199,6 +199,28 @@ def filter_guild_channel(guild_id, channel_id):
def get_online_discord_users(guild_id): def get_online_discord_users(guild_id):
embed = discord_api.get_widget(guild_id) embed = discord_api.get_widget(guild_id)
apimembers = discord_api.list_all_guild_members(guild_id)
apimembers_filtered = {}
for member in apimembers:
apimembers_filtered[member["user"]["id"]] = member
guild_roles = discord_api.get_guild_roles(guild_id)["content"]
guildroles_filtered = {}
for role in guild_roles:
guildroles_filtered[role["id"]] = role
for member in embed['members']:
apimem = apimembers_filtered.get(member["id"])
member["hoist-role"] = None
member["color"] = None
if apimem:
for roleid in reversed(apimem["roles"]):
role = guildroles_filtered[roleid]
if role["color"] != 0:
member["color"] = '{0:02x}'.format(role["color"]) #int to hex
if role["hoist"]:
member["hoist-role"] = {}
member["hoist-role"]["name"] = role["name"]
member["hoist-role"]["id"] = role["id"]
member["hoist-role"]["position"] = role["position"]
return embed['members'] return embed['members']
def get_online_embed_users(guild_id): def get_online_embed_users(guild_id):
@ -287,7 +309,7 @@ def create_unauthenticated_user():
username = username.strip() username = username.strip()
if len(username) < 2 or len(username) > 32: if len(username) < 2 or len(username) > 32:
abort(406) abort(406)
if not all(x.isalnum() or x.isspace() or "-" == x or "_" == x for x in username): if not all(x.isalpha() or x.isspace() or "-" == x or "_" == x for x in username):
abort(406) abort(406)
if not check_guild_existance(guild_id): if not check_guild_existance(guild_id):
abort(404) abort(404)

View File

@ -2,10 +2,12 @@ import requests
import sys import sys
import time import time
import json import json
from functools import partial
from cachetools import cached, TTLCache from cachetools import cached, TTLCache
from cachetools.keys import hashkey
_DISCORD_API_BASE = "https://discordapp.com/api/v6" _DISCORD_API_BASE = "https://discordapp.com/api/v6"
cache = TTLCache(200, 300) cache = TTLCache(200, 200)
def json_or_text(response): def json_or_text(response):
text = response.text text = response.text
@ -120,7 +122,7 @@ class DiscordREST:
r = self.request("GET", _endpoint) r = self.request("GET", _endpoint)
return r return r
@cached(cache) @cached(cache, key=partial(hashkey, 'get_guild_member'))
def get_guild_member(self, guild_id, user_id): def get_guild_member(self, guild_id, user_id):
_endpoint = "/guilds/{guild_id}/members/{user_id}".format(guild_id=guild_id, user_id=user_id) _endpoint = "/guilds/{guild_id}/members/{user_id}".format(guild_id=guild_id, user_id=user_id)
r = self.request("GET", _endpoint) r = self.request("GET", _endpoint)
@ -158,11 +160,30 @@ class DiscordREST:
r = self.request("GET", _endpoint) r = self.request("GET", _endpoint)
return r return r
@cached(cache, key=partial(hashkey, 'list_all_guild_members'))
def list_all_guild_members(self, guild_id):
_endpoint = "/guilds/{guild_id}/members".format(guild_id=guild_id)
count = 1
last_usrid = ""
users = []
params = {"limit": 1000}
while count > 0:
r = self.request("GET", _endpoint, params=params)
if r["success"] == True:
content = r["content"]
count = len(content)
users.extend(content)
if count > 0:
params["after"] = content[-1]["user"]["id"]
else:
count = 0
return users
##################### #####################
# User # User
##################### #####################
@cached(cache) @cached(cache, key=partial(hashkey, 'get_all_guilds'))
def get_all_guilds(self): def get_all_guilds(self):
_endpoint = "/users/@me/guilds" _endpoint = "/users/@me/guilds"
params = {} params = {}
@ -185,7 +206,7 @@ class DiscordREST:
# Widget Handler # Widget Handler
##################### #####################
@cached(cache) @cached(cache, key=partial(hashkey, 'get_widget'))
def get_widget(self, guild_id): def get_widget(self, guild_id):
_endpoint = _DISCORD_API_BASE + "/servers/{guild_id}/widget.json".format(guild_id=guild_id) _endpoint = _DISCORD_API_BASE + "/servers/{guild_id}/widget.json".format(guild_id=guild_id)
embed = self.get_guild_embed(guild_id) embed = self.get_guild_embed(guild_id)

View File

@ -51,6 +51,12 @@ color: #cfd8dc;
font-variant: small-caps; font-variant: small-caps;
} }
.role-title {
margin-bottom: -15px !important;
font-variant: normal !important;
font-size: 80% !important;
}
.divider { .divider {
background-color: #90a4ae; background-color: #90a4ae;
} }

View File

@ -173,13 +173,57 @@
var template = $('#mustache_authedusers').html(); var template = $('#mustache_authedusers').html();
Mustache.parse(template); Mustache.parse(template);
$("#discord-members").empty(); $("#discord-members").empty();
var guild_members = {};
for (var i = 0; i < discordmembers.length; i++) { for (var i = 0; i < discordmembers.length; i++) {
var member = discordmembers[i]; var member = discordmembers[i];
var rendered = Mustache.render(template, {"id": member.id.toString() + "d", "username": member.username, "avatar": member.avatar_url}); if (member["hoist-role"]) {
$("#discord-members").append(rendered); if (!(member["hoist-role"]["id"] in guild_members)) {
guild_members[member["hoist-role"]["id"]] = {};
guild_members[member["hoist-role"]["id"]]["name"] = member["hoist-role"]["name"];
guild_members[member["hoist-role"]["id"]]["members"] = [];
guild_members[member["hoist-role"]["id"]]["position"] = member["hoist-role"]["position"]
}
guild_members[member["hoist-role"]["id"]]["members"].push(member);
} else {
if (!("0" in guild_members)) {
guild_members["0"] = {};
guild_members["0"]["name"] = null;
guild_members["0"]["members"] = [];
guild_members["0"]["position"] = 0;
}
guild_members["0"]["members"].push(member);
}
}
var guild_members_arr = [];
for (key in guild_members) {
guild_members_arr.push(guild_members[key]);
}
guild_members_arr.sort(function(a, b) {
return parseInt(b.position) - parseInt(a.position);
})
var template_role = $('#mustache_memberrole').html();
Mustache.parse(template_role);
var template_user = $('#mustache_authedusers').html();
Mustache.parse(template_user);
$("#discord-members").empty();
for (var i = 0; i < guild_members_arr.length; i++) {
var roleobj = guild_members_arr[i];
if (!roleobj["name"]) {
roleobj["name"] = "Uncategorized";
}
var rendered_role = Mustache.render(template_role, {"name": roleobj["name"]});
$("#discord-members").append(rendered_role);
for (var j = 0; j < roleobj.members.length; j++) {
var member = roleobj.members[j];
var rendered_user = Mustache.render(template_user, {"id": member.id.toString() + "d", "username": member.username, "avatar": member.avatar_url});
$("#discord-members").append(rendered_user);
$( "#discorduser-" + member.id.toString() + "d").click({"member_id": member.id.toString()}, function(event) { $( "#discorduser-" + member.id.toString() + "d").click({"member_id": member.id.toString()}, function(event) {
mention_member(event.data.member_id); mention_member(event.data.member_id);
}); });
if (member.color) {
$( "#discorduser-" + member.id.toString() + "d").css("color", "#" + member.color);
}
}
} }
} }

View File

@ -123,6 +123,10 @@
<script id="mustache_usermessage" type="text/template"> <script id="mustache_usermessage" type="text/template">
<p><span id="discordmessage_{{id}}" title="{{full_timestamp}}" class="chattimestamp">{{time}}</span> <span class="chatusername">{{username}}#{{discriminator}}</span> {{{content}}}</p> <p><span id="discordmessage_{{id}}" title="{{full_timestamp}}" class="chattimestamp">{{time}}</span> <span class="chatusername">{{username}}#{{discriminator}}</span> {{{content}}}</p>
</script> </script>
<script id="mustache_memberrole" type="text/template">
<li><a class="subheader role-title">{{name}}</a></li>
</script>
{% endraw %} {% endraw %}
<script> <script>