import datetime from django.shortcuts import render, get_object_or_404 from django.http import HttpResponseRedirect from django.urls import reverse #from django.views import generic from django.contrib.auth.decorators import login_required, permission_required from django.forms import modelformset_factory, inlineformset_factory from website.settings import APPLICATION_NAME from .models import Network, Host, Channel, User, Message, Action, Notice, TempChannelKey, Join, Kick from .forms import NetworkForm, HostForm, ChannelForm def default_keywords(additional_keywords=None): default_keywords = 'RotBot, robot, bot, irc, irc bot, irc robot, ' if additional_keywords: additional_keywords = ', '.join(map(str, additional_keywords)) return (default_keywords + additional_keywords) return (default_keywords) def networks(request): networks = Network.objects.all() hosts = Host.objects.all() channels = Channel.objects.all() users = User.objects.all() messages = Message.objects.all() actions = Action.objects.all() notices = Notice.objects.all() joins = Join.objects.all() kicks = Kick.objects.all() context = { 'title': 'RotBot', 'icon': 'robot', 'description': 'Index of RotBot, the IRC robot.', 'keywords': default_keywords('index'), 'networks': networks, 'total_networks': shorten_number(networks.count()), 'total_hosts': shorten_number(hosts.count()), 'total_chanels': shorten_number(channels.count()), 'total_users': shorten_number(users.count()), 'total_messages': shorten_number(total_messages(messages)), 'total_actions': shorten_number(total_messages(actions)), 'total_notices': shorten_number(total_messages(notices)), 'total_joins': shorten_number(joins.count()), 'total_kicks': shorten_number(kicks.count()), } return render(request, 'rotbot/networks.html', context) def network(request, network_slug): network = get_object_or_404(Network, slug=network_slug) hosts = Host.objects.filter(network=network) channels = Channel.objects.filter(network=network) users = User.objects.filter(network=network) messages = Message.objects.filter(network=network) actions = Action.objects.filter(network=network) notices = Notice.objects.filter(network=network) joins = Join.objects.all() kicks = Kick.objects.all() for host in hosts: host.connection_fails = host.connection_attempts - host.connection_succeeds context = { 'parent_title': 'Networks', 'parent_url': reverse('rotbot:networks'), 'parent_icon': 'robot', 'title': network.name, 'icon': 'sitemap', 'description': 'Details of ' + network.name, 'keywords': default_keywords() + 'network.name, display, details', 'network': network, 'hosts': hosts, 'channels': channels, 'total_hosts': shorten_number(hosts.count()), 'total_chanels': shorten_number(channels.count()), 'total_users': shorten_number(users.count()), 'total_messages': shorten_number(total_messages(messages)), 'total_actions': shorten_number(total_messages(actions)), 'total_notices': shorten_number(total_messages(notices)), 'total_joins': shorten_number(joins.count()), 'total_kicks': shorten_number(kicks.count()), } return render(request, 'rotbot/network.html', context) @login_required @permission_required('rotbot.change_network', raise_exception=True) def edit_network(request, network_slug): network = get_object_or_404(Network, slug=network_slug) title = network.name HostFormSet = inlineformset_factory(Network, Host, form=HostForm) if request.method == 'POST': form = NetworkForm(request.POST, instance=network) formset = HostFormSet(request.POST, instance=network) if form.is_valid() and formset.is_valid(): form.save() formset.save() return HttpResponseRedirect(reverse('rotbot:network', args=(network.slug,))) else: form = NetworkForm(instance=network) formset = HostFormSet(instance=network) context = { 'parent_title': 'Networks', 'parent_url': reverse('rotbot:networks'), 'parent_icon': 'robot', 'title': title, 'icon': 'sitemap', 'description': 'Edit ' + title, 'keywords': default_keywords((title, 'edit')), 'network_slug': network_slug, 'form': form, 'hostformset': formset, } return render(request, 'rotbot/edit_network.html', context) @login_required @permission_required('rotbot.add_network', raise_exception=True) def add_network(request): HostFormSet = inlineformset_factory(Network, Host, form=HostForm) if request.method == 'POST': form = NetworkForm(request.POST) if form.is_valid(): network = form.save() formset = HostFormSet(request.POST, instance=network) if formset.is_valid(): formset.save() return HttpResponseRedirect(reverse('rotbot:network', args=(form.cleaned_data['slug'],))) else: formset = HostFormSet(queryset=Host.objects.none()) else: # Not a POST request. form = NetworkForm() formset = HostFormSet(queryset=Host.objects.none()) context = { 'parent_title': 'Networks', 'parent_url': reverse('rotbot:networks'), 'parent_icon': 'robot', 'title': 'Add network', 'icon': 'sitemap', 'description': 'Add new irc network to ' + APPLICATION_NAME, 'keywords': default_keywords() + 'add, add network', 'form': form, 'hostformset': formset, } return render(request, 'rotbot/add_network.html', context) @login_required @permission_required('rotbot.change_network', raise_exception=True) def delete_network(request, network_slug): network = get_object_or_404(Network, slug=network_slug) network.delete() return HttpResponseRedirect(reverse('rotbot:networks')) def channel(request, channel_slug): channel = get_object_or_404(Channel, slug=channel_slug) network = Network.objects.get(id=channel.network.id) messages = Message.objects.filter(channel=channel) actions = Action.objects.filter(channel=channel) notices = Notice.objects.filter(channel=channel) joins = Join.objects.filter(channel=channel) kicks = Kick.objects.filter(channel=channel) context = { 'parent_title': network.name, 'parent_url': reverse('rotbot:network', args=(network.slug,)), 'parent_icon': 'sitemap', 'title': channel.name, 'icon': 'hashtag', 'description': 'Details of channel %s on network %s' % (channel.name, network.name), 'keywords': default_keywords() + '%s, %s' % (network.name, channel.name), 'channel': channel, 'network': network, 'total_messages': shorten_number(total_messages(messages)), 'total_actions': shorten_number(total_messages(actions)), 'total_notices': shorten_number(total_messages(notices)), 'total_joins': shorten_number(joins.count()), 'total_kicks': shorten_number(kicks.count()), } return render(request, 'rotbot/channel.html', context) @login_required @permission_required('rotbot.change_channel', raise_exception=True) def channel_settings(request, channel_slug): channel = get_object_or_404(Channel, slug=channel_slug) network = Network.objects.get(id=channel.network_id) if request.method == 'POST': form = ChannelForm(request.POST, instance=channel) if form.is_valid(): form.save() return HttpResponseRedirect(reverse('rotbot:channel', args=(channel.slug,))) else: form = ChannelForm(instance=channel) context = { 'parent_title': network.name, 'parent_url': reverse('rotbot:network', args=(network.slug,)), 'parent_icon': 'sitemap', 'title': channel.name, 'icon': 'hashtag', 'description': 'Change settings for channel %s on network %s' % (channel.name, network.name), 'keywords': default_keywords() + 'settings, %s, %s' % (network.name, channel.name), 'channel_slug': channel.slug, 'network_slug': network.slug, 'form': form, } return render(request, 'rotbot/channel_settings.html', context) def ircauth_channel_settings(request, temp_key): key = get_object_or_404(TempChannelKey, key=temp_key) channel = Channel.objects.get(id=key.channel_id) network = Network.objects.get(id=key.network_id) if key.created > datetime.datetime.now() - datetime.timedelta(minute=10): key_expired = False else: key_expired = True if request.method == 'POST': if recent_key: form = ChannelForm(request.POST, instance=channel) if form.is_valid(): form.save() key.delete() return HttpResponseRedirect(reverse('rotbot:channel', args=(channel.slug,))) else: form = ChannelForm(instance=channel) context = { 'parent_title': network.name, 'parent_url': reverse('rotbot:network', args=(network.slug,)), 'parent_icon': 'sitemap', 'title': channel.name, 'icon': 'hashtag', 'description': 'Change settings for channel %s on network %s' % (channel.name, network.name), 'keywords': default_keywords() + 'settings, %s, %s' % (network.name, channel.name), 'channel_slug': channel.slug, 'network_slug': network.slug, 'form': form, 'temp_key': temp_key, 'key_expired': key_expired, } return render(request, 'rotbot/channel_settings.html', context) def user(request, user_slug): user = get_object_or_404(User, slug=user_slug) network = Network.objects.get(id=user.network.id) messages = Message.objects.filter(user=user) actions = Action.objects.filter(user=user) notices = Notice.objects.filter(user=user) joins = Join.objects.filter(user=user) kicks = Kick.objects.filter(kicker=user) kicked = Kick.objects.filter(kicked=user) context = { 'parent_title': network.name, 'parent_url': reverse('rotbot:network', args=(network.slug,)), 'parent_icon': 'sitemap', 'title': user.name, 'icon': 'hashtag', 'description': 'Details of user %s on network %s' % (user.name, network.name), 'keywords': default_keywords() + '%s, %s' % (network.name, user.name), 'user': user, 'network': network, 'total_messages': shorten_number(total_messages(messages)), 'total_actions': shorten_number(total_messages(actions)), 'total_notices': shorten_number(total_messages(notices)), 'total_joins': shorten_number(joins.count()), 'total_kicks': shorten_number(kicked.count()), 'total_kicked': shorten_number(kicked.count()), } return render(request, 'rotbot/user.html', context) # Helpers def total_messages(messages): total_messages = 0 for message in messages: total_messages += message.amount return total_messages def shorten_number (number): if len(str(number)) > 20: number = str(int(number /1000000000000000000)) +"E" elif len(str(number)) > 17: number = str(int(number /1000000000000000)) +"P" elif len(str(number)) > 14: number = str(int(number /1000000000000)) +"T" elif len(str(number)) > 11: number = str(int(number /1000000000)) +"G" elif len(str(number)) > 8: number = str(int(number /1000000)) +"M" elif len(str(number)) > 5: number = str(int(number /1000)) + "K" elif len(str(number)) > 4: number = str(int(number /100)) + "h" else: number = int(number) return str(number)