|
|
@@ -1,3 +1,4 @@
|
|
|
+import seaborn
|
|
|
from django.shortcuts import render, get_object_or_404
|
|
|
from django.http import HttpResponseRedirect
|
|
|
from django.urls import reverse
|
|
|
@@ -9,6 +10,21 @@ from rotbot.models import Network, Host, Channel, User, Message, Action, Notice,
|
|
|
from rotbot.forms import CurseWordForm, CurseAdjectiveForm
|
|
|
from rotbot.views.common import default_keywords, shorten_number, total_messages
|
|
|
|
|
|
+# Common
|
|
|
+def user_stats(name, event_stats, stats=False):
|
|
|
+ if not stats:
|
|
|
+ stats = {}
|
|
|
+ if not event_stats:
|
|
|
+ for stat in stats:
|
|
|
+ stats[stat][name] = 0
|
|
|
+ for stat in event_stats:
|
|
|
+ if not stat.channel.name in stats:
|
|
|
+ stats[stat.channel.name] = {}
|
|
|
+ stats[stat.channel.name][name] = stat.amount
|
|
|
+ return stats
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
def index(request):
|
|
|
networks = Network.objects.all()
|
|
|
hosts = Host.objects.all()
|
|
|
@@ -39,6 +55,7 @@ def index(request):
|
|
|
}
|
|
|
return render(request, 'rotbot/index.html', context)
|
|
|
|
|
|
+
|
|
|
def user(request, user_slug):
|
|
|
user = get_object_or_404(User, slug=user_slug)
|
|
|
network = Network.objects.get(id=user.network.id)
|
|
|
@@ -82,6 +99,58 @@ def user(request, user_slug):
|
|
|
if user.last_event_type =='sq':
|
|
|
last_event_type = 'quitting'
|
|
|
|
|
|
+ stats_dict = None
|
|
|
+ stats_dict = user_stats('joins', joins, stats=stats_dict)
|
|
|
+ stats_dict = user_stats('messages', messages, stats=stats_dict)
|
|
|
+ stats_dict = user_stats('actions', actions, stats=stats_dict)
|
|
|
+ stats_dict = user_stats('notices', notices, stats=stats_dict)
|
|
|
+ stats_dict = user_stats('kicks', kicks, stats=stats_dict)
|
|
|
+ stats_dict = user_stats('kicked', kicked, stats=stats_dict)
|
|
|
+
|
|
|
+ labels = list(list(stats_dict.values())[0].keys())
|
|
|
+
|
|
|
+ datasets = []
|
|
|
+ dicts_amount = len(stats_dict)
|
|
|
+ color_palette = seaborn.color_palette("husl", dicts_amount * 5)
|
|
|
+
|
|
|
+ i = 0
|
|
|
+ for color in color_palette:
|
|
|
+ color_list = list(color)
|
|
|
+ color_list[0] *= 255
|
|
|
+ color_list[1] *= 255
|
|
|
+ color_list[2] *= 255
|
|
|
+ color_palette[i] = tuple(color_list)
|
|
|
+ i += 1
|
|
|
+
|
|
|
+
|
|
|
+ i = 0
|
|
|
+ for dict in stats_dict:
|
|
|
+ color_gradient = linear_gradient(color_palette[i], n=87)
|
|
|
+ print(color_gradient)
|
|
|
+ datasets.append({
|
|
|
+ "label": dict,
|
|
|
+ "data": list(stats_dict[dict].values()),
|
|
|
+ "backgroundColor": 'rgba' + str(color_gradient[i]),#, 'rgba' + str(color_gradient[i]), 'rgba' + str(color_gradient[i]), 'rgba' + str(color_gradient[i]), 'rgba' + str(color_gradient[i]), 'rgba' + str(color_gradient[i]),],
|
|
|
+ "borderColor": 'rgba' + str(color_gradient[i+1]),#, 'rgba' + str(color_gradient[i+1]), 'rgba' + str(color_gradient[i+1]), 'rgba' + str(color_gradient[i+1]), 'rgba' + str(color_gradient[i+1]), 'rgba' + str(color_gradient[i+1]),],
|
|
|
+ #"pointBackgroundColor": ['rgba' + str(tuple(color_palette[i+1]))],
|
|
|
+ #"pointBorderColor": ['rgba' + str(tuple(color_palette[i+3]))],
|
|
|
+ #"pointStrokeColor": ['rgba' + str(tuple(color_palette[i+4]))],
|
|
|
+ "hoverBackgroundColor": 'rgba' + str(color_palette[i+5]),#, 'rgba' + str(tuple(color_palette[i+2])), 'rgba' + str(tuple(color_palette[i+2])), 'rgba' + str(tuple(color_palette[i+2])), 'rgba' + str(tuple(color_palette[i+2])),],
|
|
|
+ "hoverBorderColor": 'rgba' + str(color_palette[i+3]),#, 'rgba' + str(tuple(color_palette[i+3])), 'rgba' + str(tuple(color_palette[i+3])), 'rgba' + str(tuple(color_palette[i+3])), 'rgba' + str(tuple(color_palette[i+3])),],
|
|
|
+ #"hoverWidth": 2,
|
|
|
+ "borderWidth": 1,
|
|
|
+ #"borderSkipped": False,
|
|
|
+ })
|
|
|
+ i += 1
|
|
|
+
|
|
|
+ chart = {
|
|
|
+ "type": "bar",
|
|
|
+ "data": {
|
|
|
+ "labels": labels,
|
|
|
+ "datasets": datasets,
|
|
|
+ },
|
|
|
+ "options": {},
|
|
|
+ }
|
|
|
context = {
|
|
|
'parent_title': network.name,
|
|
|
'parent_url': reverse('rotbot:network', args=(network.slug,)),
|
|
|
@@ -99,9 +168,112 @@ def user(request, user_slug):
|
|
|
'total_kicks': shorten_number(kicked.count()),
|
|
|
'total_kicked': shorten_number(kicked.count()),
|
|
|
'last_event_type': last_event_type,
|
|
|
+ 'stats': stats_dict,
|
|
|
+ 'chart': chart,
|
|
|
}
|
|
|
return render(request, 'rotbot/user.html', context)
|
|
|
|
|
|
+def color_dict(gradient):
|
|
|
+ ''' Takes in a list of RGB sub-lists and returns dictionary of
|
|
|
+ colors in RGB and hex form for use in a graphing function
|
|
|
+ defined later on '''
|
|
|
+ gradients = []
|
|
|
+ for RGB in gradient:
|
|
|
+ gradients.append(tuple((RGB[0], RGB[1], RGB[2])))
|
|
|
+
|
|
|
+ return tuple(gradients)
|
|
|
+# {
|
|
|
+# "r":[RGB[0] for RGB in gradient],
|
|
|
+# "g":[RGB[1] for RGB in gradient],
|
|
|
+# "b":[RGB[2] for RGB in gradient]}
|
|
|
+
|
|
|
+
|
|
|
+def linear_gradient(start_rgb, finish_hex="#FFFFFF", n=10):
|
|
|
+ ''' returns a gradient list of (n) colors between
|
|
|
+ two hex colors. start_hex and finish_hex
|
|
|
+ should be the full six-digit color string,
|
|
|
+ inlcuding the number sign ("#FFFFFF") '''
|
|
|
+ # Starting and ending colors in RGB form
|
|
|
+ #s = hex_to_RGB(start_hex)
|
|
|
+ print(n)
|
|
|
+ s = start_rgb
|
|
|
+ f = hex_to_RGB(finish_hex)
|
|
|
+ # Initilize a list of the output colors with the starting color
|
|
|
+ RGB_list = [s]
|
|
|
+ # Calcuate a color at each evenly spaced value of t from 1 to n
|
|
|
+ for t in range(1, n):
|
|
|
+ # Interpolate RGB vector for color at the current value of t
|
|
|
+ curr_vector = [
|
|
|
+ int(s[j] + (float(t)/(n-1))*(f[j]-s[j]))
|
|
|
+ for j in range(3)
|
|
|
+ ]
|
|
|
+ # Add it to our list of output colors
|
|
|
+ RGB_list.append(curr_vector)
|
|
|
+
|
|
|
+ return color_dict(RGB_list)
|
|
|
+
|
|
|
+def hex_to_RGB(hex):
|
|
|
+ ''' "#FFFFFF" -> [255,255,255] '''
|
|
|
+ # Pass 16 to the integer function for change of base
|
|
|
+ return [int(hex[i:i+2], 16) for i in range(1,6,2)]
|
|
|
+
|
|
|
+
|
|
|
+def RGB_to_hex(RGB):
|
|
|
+ ''' [255,255,255] -> "#FFFFFF" '''
|
|
|
+ # Components need to be integers for hex to make sense
|
|
|
+ RGB = [int(x) for x in RGB]
|
|
|
+ return "#"+"".join(["0{0:x}".format(v) if v < 16 else
|
|
|
+ "{0:x}".format(v) for v in RGB])
|
|
|
+
|
|
|
+# from jchart import Chart
|
|
|
+# from jchart.config import DataSet
|
|
|
+#
|
|
|
+
|
|
|
+# class LineChart(Chart):
|
|
|
+#
|
|
|
+# chart_type = 'line'
|
|
|
+#
|
|
|
+# def get_datasets(self, channel_dict, **kwargs):
|
|
|
+# print(channel_dict)
|
|
|
+# data = []
|
|
|
+# for channel in channel_dict:
|
|
|
+# print(channel)
|
|
|
+# print(channel_dict[channel])
|
|
|
+# print(list(channel_dict[channel].values()))
|
|
|
+# print(channel_dict[channel].keys())
|
|
|
+# list(channel_dict[channel].values())
|
|
|
+# data.append(list(channel_dict[channel].values()))
|
|
|
+# print(data)
|
|
|
+#
|
|
|
+# a = DataSet(
|
|
|
+# data=data[0]
|
|
|
+# )
|
|
|
+# foobar = []
|
|
|
+# for d in data:
|
|
|
+# foobar.append(d)
|
|
|
+# return a
|
|
|
+# # [
|
|
|
+# # DataSet(
|
|
|
+# # data=data,
|
|
|
+# # #color=(55,55,55),
|
|
|
+# # )]
|
|
|
+# # [
|
|
|
+# # DataSet(
|
|
|
+# # data = [69, 30],
|
|
|
+# # #data = data
|
|
|
+# # color = (255,255,255)
|
|
|
+# # ),
|
|
|
+# # DataSet(
|
|
|
+# # data = [29, 70],
|
|
|
+# # #data = data
|
|
|
+# # color = (125,125,125)
|
|
|
+# # ),
|
|
|
+# # ]
|
|
|
+#
|
|
|
+# def get_labels(self, channel_dict, **kwargs):
|
|
|
+#
|
|
|
+# return ['Red', 'Blue']
|
|
|
+
|
|
|
|
|
|
@login_required
|
|
|
@permission_required('rotbot.add_curseword', raise_exception=True)
|