diff --git a/alliance_auth/settings.py.example b/alliance_auth/settings.py.example index eb539b20..259784de 100644 --- a/alliance_auth/settings.py.example +++ b/alliance_auth/settings.py.example @@ -61,6 +61,7 @@ INSTALLED_APPS = ( 'sigtracker', 'optimer', 'corputils', + 'fleetactivitytracking', 'notifications', ) @@ -560,6 +561,10 @@ LOGGING = { 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, + 'fleetactivitytracking': { + 'handlers': ['log_file', 'console'], + 'level': 'ERROR', + }, 'util': { 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', diff --git a/alliance_auth/urls.py b/alliance_auth/urls.py index e64b9761..9e6c5d7a 100755 --- a/alliance_auth/urls.py +++ b/alliance_auth/urls.py @@ -206,6 +206,7 @@ urlpatterns = patterns('', #corputils url(r'^corputils/$', 'corputils.views.corp_member_view', name='auth_corputils'), url(r'^corputils/(?P[0-9]+)/$', 'corputils.views.corp_member_view'), + url(r'^corputils/(?P[0-9]+)/(?P[0-9]+)/(?P[0-9]+)/$', 'corputils.views.corp_member_view', name='auth_corputils_month'), url(r'^corputils/search/$', 'corputils.views.corputils_search', name="auth_corputils_search"), url(r'^corputils/search/(?P[0-9]+)/$', 'corputils.views.corputils_search'), @@ -235,4 +236,18 @@ urlpatterns = patterns('', url(r'^notifications/$', 'notifications.views.notification_list', name='auth_notification_list'), url(r'^notifications/(\w+)/$', 'notifications.views.notification_view', name='auth_notification_view'), url(r'^remove_notifications/(\w+)/$', 'notifications.views.remove_notification', name='auth_remove_notification'), -) + + # FleetActivityTracking (FAT) + url(r'^fat/$', 'fleetactivitytracking.views.fatlink_view', name='auth_fatlink_view'), + url(r'^fat/statistics/$', 'fleetactivitytracking.views.fatlink_statistics_view', name='auth_fatlink_view_statistics'), + url(r'^fat/statistics/(?P[0-9]+)/(?P[0-9]+)/$', 'fleetactivitytracking.views.fatlink_statistics_view', name='auth_fatlink_view_statistics_month'), + url(r'^fat/user/statistics/$', 'fleetactivitytracking.views.fatlink_personal_statistics_view'), + url(r'^fat/user/statistics/(?P[0-9]+)/$', 'fleetactivitytracking.views.fatlink_personal_statistics_view', name='auth_fatlink_view_personal_statistics'), + url(r'^fat/create/$', 'fleetactivitytracking.views.create_fatlink_view', name='auth_create_fatlink_view'), + url(r'^fat/modify/$', 'fleetactivitytracking.views.modify_fatlink_view', name='auth_modify_fatlink_view'), + url(r'^fat/modify/(?P[a-zA-Z0-9_-]+)/([a-z0-9_-]+)$', + 'fleetactivitytracking.views.modify_fatlink_view'), + url(r'^fat/link/$', 'fleetactivitytracking.views.fatlink_view', name='auth_click_fatlink_view'), + url(r'^fat/link/(?P[a-zA-Z0-9]+)/(?P[a-z0-9_-]+)/$', + 'fleetactivitytracking.views.click_fatlink_view'), + ) diff --git a/corputils/views.py b/corputils/views.py index 3720e9c2..2affe638 100644 --- a/corputils/views.py +++ b/corputils/views.py @@ -2,7 +2,6 @@ from django.conf import settings from django.shortcuts import render_to_response from django.template import RequestContext from django.contrib.auth.decorators import login_required -from django.contrib.auth.decorators import permission_required from django.shortcuts import HttpResponseRedirect from collections import namedtuple @@ -14,17 +13,45 @@ from eveonline.models import EveCorporationInfo from eveonline.models import EveAllianceInfo from eveonline.models import EveCharacter from eveonline.models import EveApiKeyPair -from authentication.models import AuthServicesInfo +from fleetactivitytracking.models import Fat from util import check_if_user_has_permission from forms import CorputilsSearchForm from evelink.api import APIError import logging +import datetime logger = logging.getLogger(__name__) +class Player(object): + def __init__(self, main, user, maincorp, maincorpid, altlist, apilist, n_fats): + self.main = main + self.user = user + self.maincorp = maincorp + self.maincorpid = maincorpid + self.altlist = altlist + self.apilist = apilist + self.n_fats = n_fats + +def first_day_of_next_month(year, month): + if month == 12: + return datetime.datetime(year+1,1,1) + else: + return datetime.datetime(year, month+1, 1) + +def first_day_of_previous_month(year, month): + if month == 1: + return datetime.datetime(year-1,12,1) + else: + return datetime.datetime(year, month-1, 1) + @login_required -def corp_member_view(request, corpid = None): +def corp_member_view(request, corpid = None, year=datetime.date.today().year, month=datetime.date.today().month): + year = int(year) + month = int(month) + start_of_month = datetime.datetime(year, month, 1) + start_of_next_month = first_day_of_next_month(year, month) + start_of_previous_month = first_day_of_previous_month(year, month) logger.debug("corp_member_view called by user %s" % request.user) try: @@ -58,7 +85,6 @@ def corp_member_view(request, corpid = None): corpid = membercorplist[0][0] corp = EveCorporationInfo.objects.get(corporation_id=corpid) - Player = namedtuple("Player", ["main", "maincorp", "maincorpid", "altlist", "apilist"]) if check_if_user_has_permission(request.user, 'alliance_apis') or (check_if_user_has_permission(request.user, 'corp_apis') and (user_corp_id == corpid)): logger.debug("Retreiving and sending API-information") @@ -96,10 +122,12 @@ def corp_member_view(request, corpid = None): api_pair = None num_registered_characters = num_registered_characters + 1 characters_with_api.setdefault(mainname, Player(main=mainchar, + user=char_owner, maincorp=maincorp, maincorpid=maincorpid, altlist=[], - apilist=[]) + apilist=[], + n_fats=0) ).altlist.append(char) if api_pair: characters_with_api[mainname].apilist.append(api_pair) @@ -127,16 +155,26 @@ def corp_member_view(request, corpid = None): api_pair = None num_registered_characters = num_registered_characters + 1 characters_with_api.setdefault(mainname, Player(main=mainchar, + user=char_owner, maincorp=maincorp, maincorpid=maincorpid, altlist=[], - apilist=[]) + apilist=[], + n_fats=0) ).altlist.append(char) if api_pair: characters_with_api[mainname].apilist.append(api_pair) n_unacounted = corp.member_count - (num_registered_characters + len(characters_without_api)) + for mainname, player in characters_with_api.items(): + fats_this_month = Fat.objects.filter(user=player.user).filter(fatlink__fatdatetime__gte = start_of_month).filter(fatlink__fatdatetime__lt = start_of_next_month) + characters_with_api[mainname].n_fats = len(fats_this_month) + + if start_of_next_month > datetime.datetime.now(): + start_of_next_month = None + + if not settings.IS_CORP: context = {"membercorplist": membercorplist, "corp": corp, @@ -154,6 +192,10 @@ def corp_member_view(request, corpid = None): "characters_without_api": sorted(characters_without_api.items()), "search_form": CorputilsSearchForm()} + context["next_month"] = start_of_next_month + context["previous_month"] = start_of_previous_month + context["this_month"] = start_of_month + return render_to_response('registered/corputils.html',context, context_instance=RequestContext(request) ) return HttpResponseRedirect("/dashboard/") diff --git a/fleetactivitytracking/__init__.py b/fleetactivitytracking/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/fleetactivitytracking/admin.py b/fleetactivitytracking/admin.py new file mode 100644 index 00000000..19a3a4ce --- /dev/null +++ b/fleetactivitytracking/admin.py @@ -0,0 +1,6 @@ +from django.contrib import admin +from models import Fatlink, Fat + + +admin.site.register(Fatlink) +admin.site.register(Fat) diff --git a/fleetactivitytracking/forms.py b/fleetactivitytracking/forms.py new file mode 100644 index 00000000..3bdb8d0d --- /dev/null +++ b/fleetactivitytracking/forms.py @@ -0,0 +1,16 @@ +from django import forms +from optimer.models import optimer + +def get_fleet_list(): + fleets = optimer.objects.all() + fleetlist = [("None", "None")] + for fleet in fleets: + fleetlist.append((fleet.operation_name, fleet.operation_name)) + fleetlist.sort() + return fleetlist + + +class FatlinkForm(forms.Form): + fatname = forms.CharField(label='Name of fat-link', required=True) + duration = forms.IntegerField(label="Duration of fat-link", required=True, initial=30, min_value=1, max_value=2147483647) + fleet = forms.ChoiceField(label="Fleet", choices=get_fleet_list()) \ No newline at end of file diff --git a/fleetactivitytracking/models.py b/fleetactivitytracking/models.py new file mode 100644 index 00000000..d10806a1 --- /dev/null +++ b/fleetactivitytracking/models.py @@ -0,0 +1,37 @@ +from django.db import models +from django.contrib.auth.models import User +from optimer.models import optimer +from eveonline.models import EveCharacter +from datetime import datetime +from datetime import date +from django.utils import timezone + +def get_sentinel_user(): + return User.objects.get_or_create(username='deleted')[0] + +class Fatlink(models.Model): + fatdatetime = models.DateTimeField(default=timezone.now()) + duration = models.PositiveIntegerField() + fleet = models.CharField(max_length=254, default="") + name = models.CharField(max_length=254) + hash = models.CharField(max_length=254, unique=True) + creator = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user)) + + def __str__(self): + return self.name + + +class Fat(models.Model): + character = models.ForeignKey(EveCharacter, on_delete=models.CASCADE) + fatlink = models.ForeignKey(Fatlink) + system = models.CharField(max_length=30) + shiptype = models.CharField(max_length=30) + station = models.CharField(max_length=125) + user = models.ForeignKey(User) + + class Meta: + unique_together = (('character', 'fatlink'),) + + def __str__(self): + output = "Fat-link for %s" % self.character.character_name + return output.encode('utf-8') diff --git a/fleetactivitytracking/views.py b/fleetactivitytracking/views.py new file mode 100644 index 00000000..e4b21fbe --- /dev/null +++ b/fleetactivitytracking/views.py @@ -0,0 +1,254 @@ +from django.conf import settings +from django.shortcuts import HttpResponseRedirect +from django.shortcuts import render_to_response +from django.core.exceptions import ObjectDoesNotExist +from django.contrib.auth.decorators import login_required +from django.contrib.auth.decorators import permission_required +from django.template import RequestContext +from django.core.exceptions import ValidationError +from django.utils import timezone + +from eveonline.models import EveCharacter +from eveonline.models import EveCorporationInfo +from eveonline.managers import EveManager +from util import check_if_user_has_permission +from forms import FatlinkForm +from models import Fatlink, Fat + +from slugify import slugify + +from collections import OrderedDict + +import string +import random +import datetime + + +import logging + +logger = logging.getLogger(__name__) + + +class CorpStat(object): + def __init__(self, corp_id, corp=None, blue=False): + if corp: + self.corp = corp + else: + self.corp = EveCorporationInfo.objects.get(corporation_id=corp_id) + self.n_fats = 0 + self.blue = blue + + def avg_fat(self): + return "%.2f" % (float(self.n_fats)/float(self.corp.member_count)) + +def first_day_of_next_month(year, month): + if month == 12: + return datetime.datetime(year+1,1,1) + else: + return datetime.datetime(year, month+1, 1) + +def first_day_of_previous_month(year, month): + if month == 1: + return datetime.datetime(year-1,12,1) + else: + return datetime.datetime(year, month-1, 1) + + +@login_required +def fatlink_view(request): + # Will show the last 5 or so fatlinks clicked by user. + # If the user has the right privileges the site will also show the latest fatlinks with the options to add VIPs and + # manually add players. + user = request.user + logger.debug("fatlink_view called by user %s" % request.user) + + latest_fats = Fat.objects.filter(user=user).order_by('-id')[:5] + if check_if_user_has_permission(user, 'fleetactivitytracking'): + latest_links = Fatlink.objects.all().order_by('-id')[:5] + context = {'user':user, 'fats': latest_fats, 'fatlinks': latest_links} + + else: + context = {'user':user, 'fats': latest_fats} + + return render_to_response('registered/fatlinkview.html', context, context_instance=RequestContext(request)) + + +@login_required +@permission_required('auth.fleetactivitytracking_statistics') +def fatlink_statistics_view(request, year=datetime.date.today().year, month=datetime.date.today().month): + year = int(year) + month = int(month) + start_of_month = datetime.datetime(year, month, 1) + start_of_next_month = first_day_of_next_month(year, month) + start_of_previous_month = first_day_of_previous_month(year, month) + + fatStats = OrderedDict() + + if settings.IS_CORP: + fatStats[settings.CORP_NAME] = CorpStat(settings.CORP_ID) + else: + alliance_corps = EveCorporationInfo.objects.filter(alliance__alliance_id=settings.ALLIANCE_ID) + for corp in alliance_corps: + fatStats[corp.corporation_name] = CorpStat(corp.corporation_id, corp=corp) + + fatlinks_in_span = Fatlink.objects.filter(fatdatetime__gte = start_of_month).filter(fatdatetime__lt = start_of_next_month) + + for fatlink in fatlinks_in_span: + fats_in_fatlink = Fat.objects.filter(fatlink=fatlink) + for fat in fats_in_fatlink: + fatStats.setdefault(fat.character.corporation_name, + CorpStat(fat.character.corporation_id, blue=True) + ).n_fats += 1 + + fatStatsList = [fatStat for corp_name, fatStat in fatStats.items()] + fatStatsList.sort(key=lambda stat: stat.corp.corporation_name) + fatStatsList.sort(key=lambda stat: (stat.n_fats, stat.n_fats/stat.corp.member_count), reverse=True) + + if datetime.datetime.now() > start_of_next_month: + context = {'fatStats':fatStatsList, 'month':start_of_month.strftime("%B"), 'year':year, 'previous_month': start_of_previous_month,'next_month': start_of_next_month} + else: + context = {'fatStats':fatStatsList, 'month':start_of_month.strftime("%B"), 'year':year, 'previous_month': start_of_previous_month} + + return render_to_response('registered/fatlinkstatisticsview.html', context, context_instance=RequestContext(request)) + + + +@login_required +def fatlink_personal_statistics_view(request, year=datetime.date.today().year): + year = int(year) + user = request.user + logger.debug("fatlink_personal_statistics_view called by user %s" % request.user) + + personal_fats = Fat.objects.filter(user=user).order_by('id') + + + + monthlystats = {datetime.date(year, month, 1).strftime("%h"):0 for month in range(1,13)} + + for fat in personal_fats: + fatdate = fat.fatlink.fatdatetime + if fatdate.year == year: + monthlystats[fatdate.strftime("%h")] += 1 + + if datetime.datetime.now() > datetime.datetime(year+1, 1, 1): + context = {'user':user, 'monthlystats': monthlystats, 'year':year, 'previous_year':year-1, 'next_year':year+1} + else: + context = {'user':user, 'monthlystats': monthlystats, 'year':year, 'previous_year':year-1} + + return render_to_response('registered/fatlinkpersonalstatisticsview.html', context, context_instance=RequestContext(request)) + + +@login_required +def click_fatlink_view(request, hash, fatname): + # Take IG-header data and register the fatlink if not existing already. + # use obj, created = Fat.objects.get_or_create() + # onload="CCPEVE.requestTrust('http://www.mywebsite.com')" + + if 'HTTP_EVE_TRUSTED' in request.META and request.META['HTTP_EVE_TRUSTED'] == "Yes": + # Retrieve the latest fatlink using the hash. + try: + fatlink = Fatlink.objects.filter(hash=hash)[0] + valid = True + + if (timezone.now() - fatlink.fatdatetime) < datetime.timedelta(seconds=(fatlink.duration*60)): + active = True + + character = EveManager.get_character_by_id(request.META['HTTP_EVE_CHARID']) + + if character: + fat = Fat() + fat.system = request.META['HTTP_EVE_SOLARSYSTEMNAME'] + fat.station = request.META['HTTP_EVE_STATIONNAME'] + fat.shiptype = request.META['HTTP_EVE_SHIPTYPENAME'] + fat.fatlink = fatlink + fat.character = character + fat.user = character.user + try: + fat.full_clean() + fat.save() + context = {'trusted': True, 'registered': True} + except ValidationError as e: + messages = [] + for errorname, message in e.message_dict.items(): + messages.append(message[0].decode()) + context = {'trusted': True, 'errormessages': messages} + else: + context = {'character_id': request.META['HTTP_EVE_CHARID'], 'character_name': request.META['HTTP_EVE_CHARNAME']} + return render_to_response('public/characternotexisting.html', context, context_instance=RequestContext(request)) + else: + context = {'trusted': True, 'expired': True} + except ObjectDoesNotExist: + context = {'trusted': True} + else: + context = {'trusted': False, 'fatname': fatname} + return render_to_response('public/clickfatlinkview.html', context, context_instance=RequestContext(request)) + + +@login_required +@permission_required('auth.fleetactivitytracking') +def create_fatlink_view(request): + logger.debug("create_fatlink_view called by user %s" % request.user) + if request.method == 'POST': + logger.debug("Post request to create_fatlink_view by user %s" % request.user) + form = FatlinkForm(request.POST) + if 'submit_fat' in request.POST: + logger.debug("Submitting fleetactivitytracking by user %s" % request.user) + if form.is_valid(): + fatlink = Fatlink() + fatlink.name = slugify(form.cleaned_data["fatname"]) + fatlink.fleet = form.cleaned_data["fleet"] + fatlink.duration = form.cleaned_data["duration"] + fatlink.creator = request.user + fatlink.hash = ''.join(random.choice(string.ascii_letters+string.digits) for i in range(10)) + try: + fatlink.full_clean() + fatlink.save() + except ValidationError as e: + form = FatlinkForm() + messages = [] + for errorname, message in e.message_dict.items(): + messages.append(message[0].decode()) + context = {'form': form, 'errormessages': messages} + return render_to_response('registered/fatlinkformatter.html', context, context_instance=RequestContext(request)) + else: + form = FatlinkForm() + context = {'form': form, 'badrequest': True} + return render_to_response('registered/fatlinkformatter.html', context, context_instance=RequestContext(request)) + return HttpResponseRedirect('/fat/') + + else: + form = FatlinkForm() + logger.debug("Returning empty form to user %s" % request.user) + + context = {'form': form} + + return render_to_response('registered/fatlinkformatter.html', context, context_instance=RequestContext(request)) + + +@login_required +@permission_required('auth.fleetactivitytracking') +def modify_fatlink_view(request, hash=""): + logger.debug("modify_fatlink_view called by user %s" % request.user) + if not hash: + return HttpResponseRedirect('/fat/') + + fatlink = Fatlink.objects.filter(hash=hash)[0] + + if(request.GET.get('removechar')): + character_id = request.GET.get('removechar') + character = EveCharacter.objects.get(character_id=character_id) + logger.debug("Removing character %s from fleetactivitytracking %s" % (character.character_name ,fatlink.name)) + + Fat.objects.filter(fatlink=fatlink).filter(character=character).delete() + + if(request.GET.get('deletefat')): + logger.debug("Removing fleetactivitytracking %s" % fatlink.name) + fatlink.delete() + return HttpResponseRedirect('/fat/') + + registered_fats = Fat.objects.filter(fatlink=fatlink).order_by('character') + + context = {'fatlink':fatlink, 'registered_fats':registered_fats} + + return render_to_response('registered/fatlinkmodify.html', context, context_instance=RequestContext(request)) + diff --git a/requirements.txt b/requirements.txt index 1f4ddbac..fd3dec95 100755 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ passlib requests>=2.9.1 bcrypt zeroc-ice +slugify # Django Stuff # django==1.6.5 diff --git a/stock/templates/public/base.html b/stock/templates/public/base.html index 5afb5ac6..b42316b9 100755 --- a/stock/templates/public/base.html +++ b/stock/templates/public/base.html @@ -176,6 +176,12 @@ {% endif %} +
  • + Fleet Activity Tracking +
  • +
  • + + + + + + + + + + + Fleet participation + + + + + + + {% block extra_css %}{% endblock extra_css %} + + + + +
    + + + + +
    + + +
    +

    Character not found!

    +
    +
    +
    +
    +
    {{ character_name }}
    +
    +
    + +
    +
    + + This character is not part of any registered API-key. You must go to API key management and add an API with the character on before being able to click fleet attendance links. +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + diff --git a/stock/templates/public/clickfatlinkview.html b/stock/templates/public/clickfatlinkview.html new file mode 100644 index 00000000..a6526179 --- /dev/null +++ b/stock/templates/public/clickfatlinkview.html @@ -0,0 +1,96 @@ +{% load staticfiles %} + + + + + + + + + + + + + Fleet participation + + + + + + + {% block extra_css %}{% endblock extra_css %} + + + + +
    + + + + +
    + + +
    + {% if registered %}

    Fleet registered!

    {% elif expired%}

    This link has expired.

    {% elif errormessages%}

    Something unhappened occured.

    {% else %}

    Invalid link.

    {% endif %} +
    + {% for message in errormessages %} + + {% endfor %} + {% if trusted %} +
    +
    +
    +
    Fleet stats
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + {% else %} + + {% endif %} +
    +
    + + + + + + + + + diff --git a/stock/templates/registered/corputils.html b/stock/templates/registered/corputils.html index 8fefef81..68c6eeb8 100644 --- a/stock/templates/registered/corputils.html +++ b/stock/templates/registered/corputils.html @@ -57,6 +57,23 @@
  • {% endif %} +
  • + +
  • {{ char.character_name }}

    {% endfor %} + + {{ player.n_fats }} + {% for char in player.altlist %}

    Killboard

    diff --git a/stock/templates/registered/fatlinkformatter.html b/stock/templates/registered/fatlinkformatter.html new file mode 100644 index 00000000..e94b4b85 --- /dev/null +++ b/stock/templates/registered/fatlinkformatter.html @@ -0,0 +1,36 @@ +{% extends "public/base.html" %} +{% load bootstrap %} +{% load staticfiles %} + +{% block title %}Alliance Auth - Fatlink Create{% endblock %} + +{% block page_title %}Create Fatlink{% endblock page_title %} +{% block extra_css %} + {% endblock extra_css %} + +{% block content %} +
    +

    Create Fleet Operation

    + +
    + {% if badrequest %} + + {% endif %} + {% for message in errormessages %} + + {% endfor %} +
    +
    + +
    +
    +
    +
    + +{% endblock content %} + diff --git a/stock/templates/registered/fatlinkmodify.html b/stock/templates/registered/fatlinkmodify.html new file mode 100644 index 00000000..02501414 --- /dev/null +++ b/stock/templates/registered/fatlinkmodify.html @@ -0,0 +1,54 @@ +{% extends "public/base.html" %} +{% load bootstrap %} +{% load staticfiles %} + +{% block title %}Alliance Auth{% endblock %} +{% block page_title %}Fatlink view{% endblock page_title %} + +{% block content %} +
    +

    Edit fatlink "{{ fatlink.name }}" +
    +
    + +
    +
    +

    +

    Registered characters

    + + + + + + + + + + {% for fat in registered_fats %} + + + + {% if fat.station != "None" %} + + {% else %} + + {% endif %} + + + + + {% endfor %} +
    UserCharacterSystemShipEve Time
    {{ fat.user }}{{ fat.character.character_name }}Docked in {{ fat.system }}{{ fat.system }}{{ fat.shiptype }}{{ fat.fatlink.fatdatetime }} +
    + +
    +
    +
    + + + + +{% endblock content %} diff --git a/stock/templates/registered/fatlinkpersonalstatisticsview.html b/stock/templates/registered/fatlinkpersonalstatisticsview.html new file mode 100644 index 00000000..7995ab7a --- /dev/null +++ b/stock/templates/registered/fatlinkpersonalstatisticsview.html @@ -0,0 +1,39 @@ +{% extends "public/base.html" %} +{% load bootstrap %} +{% load staticfiles %} + +{% block title %}Alliance Auth{% endblock %} +{% block page_title %}Personal fatlink statistics{% endblock page_title %} + +{% block content %} +
    +

    Participation data statistics for {{ year }} +
    + + + + {% if next_year %} + + + + {% endif %} +
    +

    + + + + + + {% for month, n_fats in monthlystats.items %} + + + + + {% endfor %} +
    MonthFats
    {{ month }}{{ n_fats }}
    +
    + + + + +{% endblock content %} diff --git a/stock/templates/registered/fatlinkstatisticsview.html b/stock/templates/registered/fatlinkstatisticsview.html new file mode 100644 index 00000000..c3f0a2dd --- /dev/null +++ b/stock/templates/registered/fatlinkstatisticsview.html @@ -0,0 +1,49 @@ +{% extends "public/base.html" %} +{% load bootstrap %} +{% load staticfiles %} + +{% block title %}Alliance Auth{% endblock %} +{% block page_title %}Fatlink statistics{% endblock page_title %} + +{% block content %} +
    +

    Participation data statistics for {{ month }}, {{ year }} +
    + + + + {% if next_month %} + + + + {% endif %} +
    +

    + + + + + + + + + + {% for corpStat in fatStats %} + + + + + + + + + {% endfor %} +
    TickerCorpMembersFatsAverage fats
    + + [{{ corpStat.corp.corporation_ticker }}]{{ corpStat.corp.corporation_name }}{{ corpStat.corp.member_count }}{{ corpStat.n_fats }}{{ corpStat.avg_fat }}
    +
    + + + + +{% endblock content %} diff --git a/stock/templates/registered/fatlinkview.html b/stock/templates/registered/fatlinkview.html new file mode 100644 index 00000000..a784564f --- /dev/null +++ b/stock/templates/registered/fatlinkview.html @@ -0,0 +1,98 @@ +{% extends "public/base.html" %} +{% load bootstrap %} +{% load staticfiles %} + +{% block title %}Alliance Auth{% endblock %} +{% block page_title %}Fatlink view{% endblock page_title %} + +{% block content %} +
    +

    Participation data

    + + + + + +
    +

    Most recent clicked fatlinks +

    +
    + + + +
    + + + + + + + + + {% for fat in fats %} + + + + {% if fat.station != "None" %} + + {% else %} + + {% endif %} + + + + {% endfor %} +
    fatnameCharacterSystemShipEve Time
    {{ fat.fatlink.name }}{{ fat.character.character_name }}Docked in {{ fat.system }}{{ fat.system }}{{ fat.shiptype }}{{ fat.fatlink.fatdatetime }}
    + + {% if perms.auth.fleetactivitytracking%} + + + + + + +
    +

    Most recent fatlinks +

    +
    + + + + + + + +
    + + + + + + + + + + {% for link in fatlinks %} + + + + + + + + + {% endfor %} + +
    NameCreatorFleetEve TimeDurationEdit
    {{ link.name }}{{ link.creator.username }}{{ link.fleet }}{{ link.fatdatetime }}{{ link.duration }} + + + +
    + {% endif %} +
    + + + + +{% endblock content %} diff --git a/util/__init__.py b/util/__init__.py index 94e6fa2e..ae5137c2 100755 --- a/util/__init__.py +++ b/util/__init__.py @@ -16,6 +16,8 @@ def bootstrap_permissions(): Permission.objects.get_or_create(codename="group_management", content_type=ct, name="group_management") Permission.objects.get_or_create(codename="jabber_broadcast", content_type=ct, name="jabber_broadcast") Permission.objects.get_or_create(codename="jabber_broadcast_all", content_type=ct, name="jabber_broadcast_all") + Permission.objects.get_or_create(codename="fleetactivitytracking", content_type=ct, name="fleetactivitytracking") + Permission.objects.get_or_create(codename="fleetactivitytracking_statistics", content_type=ct, name="fleetactivitytracking_statistics") Permission.objects.get_or_create(codename="human_resources", content_type=ct, name="human_resources") Permission.objects.get_or_create(codename="blue_member", content_type=ct, name="blue_member") Permission.objects.get_or_create(codename="alliance_apis", content_type=ct, name="alliance_apis")