Restructure settings.py.example

Add help text to State model
Remove navbar group headings
Fix registration email pluralization
Group memberships on state admin page
Attempt to prevent resetting of state if set on profile admin manually
Embed readthedocs on help page
Rename CorpStats API Index to Registration Index
Default corputils view to main character's corp if available
Correct Application characters listing
Correct string coercion of optimers
Improve readability of SRP values with intcomma
Beautify tables by embeding in panels
Replace slugify with py3-friendly python-slugify
This commit is contained in:
Adarnof 2017-03-25 16:28:26 -04:00
parent 963cecb365
commit 13b0dbc960
26 changed files with 360 additions and 292 deletions

View File

@ -17,31 +17,6 @@ import djcelery
from django.contrib import messages from django.contrib import messages
from celery.schedules import crontab from celery.schedules import crontab
djcelery.setup_loader()
# Celery configuration
BROKER_URL = 'redis://localhost:6379/0'
CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler"
CELERYBEAT_SCHEDULE = dict()
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ''
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
@ -68,7 +43,7 @@ INSTALLED_APPS = [
'geelweb.django.navhelper', 'geelweb.django.navhelper',
'bootstrap_pagination', 'bootstrap_pagination',
# Services # Services - comment out if not used
'services.modules.mumble', 'services.modules.mumble',
'services.modules.discord', 'services.modules.discord',
'services.modules.discourse', 'services.modules.discourse',
@ -83,6 +58,25 @@ INSTALLED_APPS = [
'services.modules.teamspeak3', 'services.modules.teamspeak3',
] ]
#####################################################
##
## Django Project Configuration
##
#####################################################
# You shouldn't need to touch most of this.
# Scroll down for Auth Configuration
#####################################################
djcelery.setup_loader()
# Celery configuration
BROKER_URL = 'redis://localhost:6379/0'
CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler"
CELERYBEAT_SCHEDULE = dict()
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MIDDLEWARE = [ MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
@ -137,20 +131,6 @@ TEMPLATES = [
WSGI_APPLICATION = 'alliance_auth.wsgi.application' WSGI_APPLICATION = 'alliance_auth.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'alliance_auth',
'USER': 'allianceserver',
'PASSWORD': '',
'HOST': '127.0.0.1',
'PORT': '3306',
},
}
# Password validation # Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
@ -213,20 +193,46 @@ CACHES = {
##################################################### #####################################################
## ##
## Auth configuration starts here ## Auth Configuration
## ##
##################################################### #####################################################
#################### ###############################
# Required Django Settings
###############################
# SECRET_KEY - Random alphanumeric string for cryptographic signing
# http://www.miniwebtool.com/django-secret-key-generator/
# DEBUG - True to display stack traces when errors are encountered.
# Set this False once auth is installed and working for security.
# ALLOWED_HOSTS - A list of hosts to serve content on. Wildcards accepted.
# Requests for hosts not listed here will be rejected.
# Example: ['example.com', 'auth.example.com']
# DATABASES - Auth database connection information.
################################
SECRET_KEY = ''
DEBUG = True
ALLOWED_HOSTS = []
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'alliance_auth',
'USER': 'allianceserver',
'PASSWORD': '',
'HOST': '127.0.0.1',
'PORT': '3306',
},
}
####################################
# SITE_NAME - Name of the auth site. # SITE_NAME - Name of the auth site.
#################### ####################################
SITE_NAME = 'Alliance Auth' SITE_NAME = 'Alliance Auth'
################# #################
# EMAIL SETTINGS # EMAIL SETTINGS
################# #################
# DEFAULT_FROM_EMAIL - no-reply email address # DEFAULT_FROM_EMAIL - no-reply email address
# DOMAIN - The Alliance Auth domain (or subdomain) address, starting with http:// # DOMAIN - The Alliance Auth domain (or subdomain) address, no leading http://
# EMAIL_HOST - SMTP Server URL # EMAIL_HOST - SMTP Server URL
# EMAIL_PORT - SMTP Server PORT # EMAIL_PORT - SMTP Server PORT
# EMAIL_HOST_USER - Email Username (for gmail, the entire address) # EMAIL_HOST_USER - Email Username (for gmail, the entire address)
@ -234,7 +240,7 @@ SITE_NAME = 'Alliance Auth'
# EMAIL_USE_TLS - Set to use TLS encryption # EMAIL_USE_TLS - Set to use TLS encryption
################# #################
DEFAULT_FROM_EMAIL = 'no-reply@example.com' DEFAULT_FROM_EMAIL = 'no-reply@example.com'
DOMAIN = 'https://example.com' DOMAIN = 'example.com'
EMAIL_HOST = 'smtp.gmail.com' EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587 EMAIL_PORT = 587
EMAIL_HOST_USER = '' EMAIL_HOST_USER = ''
@ -255,13 +261,13 @@ ESI_SSO_CALLBACK_URL = ''
################# #################
# Login Settings # Login Settings
################# #################
# LOGIN_REDIRECT_URL - default destination when logging in if no redirect specified
# LOGOUT_REDIRECT_URL - destination after logging out
# Both of these redirects accept values as per the django redirect shortcut # Both of these redirects accept values as per the django redirect shortcut
# https://docs.djangoproject.com/en/1.10/topics/http/shortcuts/#redirect # https://docs.djangoproject.com/en/1.10/topics/http/shortcuts/#redirect
# - url names eg 'authentication:dashboard' # - url names eg 'authentication:dashboard'
# - relative urls eg '/dashboard' # - relative urls eg '/dashboard'
# - absolute urls eg 'http://example.com/dashboard' # - absolute urls eg 'http://example.com/dashboard'
# LOGIN_REDIRECT_URL - default destination when logging in if no redirect specified
# LOGOUT_REDIRECT_URL - destination after logging out
# LOGIN_TOKEN_SCOPES - scopes required on new tokens when logging in. Cannot be blank. # LOGIN_TOKEN_SCOPES - scopes required on new tokens when logging in. Cannot be blank.
# ACCOUNT_ACTIVATION_DAYS - number of days email verification tokens are valid for # ACCOUNT_ACTIVATION_DAYS - number of days email verification tokens are valid for
################## ##################
@ -270,6 +276,12 @@ LOGOUT_REDIRECT_URL = 'authentication:dashboard'
LOGIN_TOKEN_SCOPES = ['esi-characters.read_opportunities.v1'] LOGIN_TOKEN_SCOPES = ['esi-characters.read_opportunities.v1']
ACCOUNT_ACTIVATION_DAYS = 1 ACCOUNT_ACTIVATION_DAYS = 1
#####################################################
##
## Service Configuration
##
#####################################################
##################### #####################
# Alliance Market # Alliance Market
##################### #####################
@ -402,10 +414,8 @@ DISCOURSE_SSO_SECRET = ''
# IPS4 Configuration # IPS4 Configuration
##################################### #####################################
# IPS4_URL - Base URL of the IPS4 install (no trailing slash). Include http:// # IPS4_URL - Base URL of the IPS4 install (no trailing slash). Include http://
# IPS4_API_KEY - API key provided by IPS4
##################################### #####################################
IPS4_URL = '' IPS4_URL = ''
IPS4_API_KEY = ''
IPS4_DB = { IPS4_DB = {
'ENGINE': 'django.db.backends.mysql', 'ENGINE': 'django.db.backends.mysql',
'NAME': 'alliance_ips4', 'NAME': 'alliance_ips4',
@ -452,9 +462,11 @@ FLEETUP_USER_ID = ''
FLEETUP_API_ID = '' FLEETUP_API_ID = ''
FLEETUP_GROUP_ID = '' FLEETUP_GROUP_ID = ''
##################################### #####################################################
# Logging Configuration ##
##################################### ## Logging Configuration
##
#####################################################
# Set log_file and console level to desired state: # Set log_file and console level to desired state:
# DEBUG - basically stack trace, explains every step # DEBUG - basically stack trace, explains every step
# INFO - model creation, deletion, updates, etc # INFO - model creation, deletion, updates, etc
@ -559,12 +571,22 @@ LOGGING = {
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'django': { 'django': {
'handlers': ['log_file', 'console', 'notifications'], 'handlers': ['log_file', 'console'],
'level': 'ERROR', 'level': 'ERROR',
}, },
} }
} }
#####################################################
##
## Magic Block
##
#####################################################
# This block automagically inserts needed settings if
# certain services are installed.
# Don't touch.
#########################################
# Conditionally add databases only if configured # Conditionally add databases only if configured
if 'services.modules.phpbb3' in INSTALLED_APPS: if 'services.modules.phpbb3' in INSTALLED_APPS:
DATABASES['phpbb3'] = PHPBB3_DB DATABASES['phpbb3'] = PHPBB3_DB

View File

@ -5,9 +5,12 @@ from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils.text import slugify from django.utils.text import slugify
from django import forms from django import forms
from django.db.models.signals import post_save
from authentication.models import State, get_guest_state, CharacterOwnership, UserProfile from authentication.models import State, get_guest_state, CharacterOwnership, UserProfile
from authentication.signals import reassess_on_profile_save
from alliance_auth.hooks import get_hooks from alliance_auth.hooks import get_hooks
from services.hooks import ServicesHook from services.hooks import ServicesHook
from services.tasks import validate_services
def make_service_hooks_update_groups_action(service): def make_service_hooks_update_groups_action(service):
@ -92,6 +95,18 @@ class StateForm(forms.ModelForm):
class StateAdmin(admin.ModelAdmin): class StateAdmin(admin.ModelAdmin):
form = StateForm form = StateForm
fieldsets = (
(None, {
'fields': ('name', 'permissions', 'priority'),
}),
('Membership', {
'classes': ('collapse',),
'fields': ('public', 'member_characters', 'member_corporations', 'member_alliances'),
})
)
filter_horizontal = ['member_characters', 'member_corporations', 'member_alliances', 'permissions']
@staticmethod @staticmethod
def has_delete_permission(request, obj=None): def has_delete_permission(request, obj=None):
if obj == get_guest_state(): if obj == get_guest_state():
@ -99,4 +114,18 @@ class StateAdmin(admin.ModelAdmin):
admin.site.register(CharacterOwnership) admin.site.register(CharacterOwnership)
admin.site.register(UserProfile)
class UserProfileAdminForm(forms.ModelForm):
def save(self, *args, **kwargs):
# prevent state reassessment to allow manually overriding states
post_save.disconnect(reassess_on_profile_save, sender=UserProfile)
model = super(UserProfileAdminForm, self).save(*args, **kwargs)
post_save.connect(reassess_on_profile_save, sender=UserProfile)
validate_services(model.user)
return model
@admin.register(UserProfile)
class UserProfileAdmin(admin.ModelAdmin):
form = UserProfileAdminForm

View File

@ -149,10 +149,12 @@ def recreate_authservicesinfo(apps, schema_editor):
# repopulate main characters # repopulate main characters
for profile in UserProfile.objects.exclude(main_character__isnull=True).select_related('user', 'main_character'): for profile in UserProfile.objects.exclude(main_character__isnull=True).select_related('user', 'main_character'):
AuthServicesInfo.objects.update_or_create(user=profile.user, defaults={'main_char_id': profile.main_character.character_id}) AuthServicesInfo.objects.update_or_create(user=profile.user,
defaults={'main_char_id': profile.main_character.character_id})
# repopulate states we understand # repopulate states we understand
for profile in UserProfile.objects.exclude(state__name='Guest').filter(state__name__in=['Member', 'Blue']).select_related('user', 'state'): for profile in UserProfile.objects.exclude(state__name='Guest').filter(
state__name__in=['Member', 'Blue']).select_related('user', 'state'):
AuthServicesInfo.objects.update_or_create(user=profile.user, defaults={'state': profile.state.name}) AuthServicesInfo.objects.update_or_create(user=profile.user, defaults={'state': profile.state.name})
@ -196,11 +198,15 @@ class Migration(migrations.Migration):
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=20, unique=True)), ('name', models.CharField(max_length=20, unique=True)),
('priority', models.IntegerField(unique=True)), ('priority', models.IntegerField(unique=True,
('public', models.BooleanField(default=False)), help_text="Users get assigned the state with the highest priority available to them.")),
('member_alliances', models.ManyToManyField(blank=True,to='eveonline.EveAllianceInfo')), ('public', models.BooleanField(default=False, help_text="Make this state available to any character.")),
('member_characters', models.ManyToManyField(blank=True,to='eveonline.EveCharacter')), ('member_alliances', models.ManyToManyField(blank=True, to='eveonline.EveAllianceInfo',
('member_corporations', models.ManyToManyField(blank=True,to='eveonline.EveCorporationInfo')), help_text="Alliances to whose members this state is available.")),
('member_characters', models.ManyToManyField(blank=True, to='eveonline.EveCharacter',
help_text="Characters to which this state is available.")),
('member_corporations', models.ManyToManyField(blank=True, to='eveonline.EveCorporationInfo',
help_text="Corporations to whose members this state is available.")),
('permissions', models.ManyToManyField(blank=True, to='auth.Permission')), ('permissions', models.ManyToManyField(blank=True, to='auth.Permission')),
], ],
options={ options={
@ -215,7 +221,8 @@ class Migration(migrations.Migration):
models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL,
to='eveonline.EveCharacter')), to='eveonline.EveCharacter')),
('state', models.ForeignKey(on_delete=models.SET(authentication.models.get_guest_state), ('state', models.ForeignKey(on_delete=models.SET(authentication.models.get_guest_state),
to='authentication.State', default=authentication.models.get_guest_state_pk)), to='authentication.State',
default=authentication.models.get_guest_state_pk)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile',
to=settings.AUTH_USER_MODEL)), to=settings.AUTH_USER_MODEL)),
], ],

View File

@ -4,6 +4,8 @@ from django.db import models
from django.contrib.auth.models import User, Permission from django.contrib.auth.models import User, Permission
from authentication.managers import CharacterOwnershipManager, StateManager from authentication.managers import CharacterOwnershipManager, StateManager
from eveonline.models import EveCharacter, EveCorporationInfo, EveAllianceInfo from eveonline.models import EveCharacter, EveCorporationInfo, EveAllianceInfo
from notifications import notify
from django.utils.translation import ugettext_lazy as _
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -13,12 +15,16 @@ logger = logging.getLogger(__name__)
class State(models.Model): class State(models.Model):
name = models.CharField(max_length=20, unique=True) name = models.CharField(max_length=20, unique=True)
permissions = models.ManyToManyField(Permission, blank=True) permissions = models.ManyToManyField(Permission, blank=True)
priority = models.IntegerField(unique=True) priority = models.IntegerField(unique=True,
help_text="Users get assigned the state with the highest priority available to them.")
member_characters = models.ManyToManyField(EveCharacter, blank=True) member_characters = models.ManyToManyField(EveCharacter, blank=True,
member_corporations = models.ManyToManyField(EveCorporationInfo, blank=True) help_text="Characters to which this state is available.")
member_alliances = models.ManyToManyField(EveAllianceInfo, blank=True) member_corporations = models.ManyToManyField(EveCorporationInfo, blank=True,
public = models.BooleanField(default=False) help_text="Corporations to whose members this state is available.")
member_alliances = models.ManyToManyField(EveAllianceInfo, blank=True,
help_text="Alliances to whose members this state is available.")
public = models.BooleanField(default=False, help_text="Make this state available to any character.")
objects = StateManager() objects = StateManager()
@ -62,6 +68,9 @@ class UserProfile(models.Model):
if commit: if commit:
logger.info('Updating {} state to {}'.format(self.user, self.state)) logger.info('Updating {} state to {}'.format(self.user, self.state))
self.save(update_fields=['state']) self.save(update_fields=['state'])
notify(self.user, _('State Changed'),
_('Your user state has been changed to %(state)s') % ({'state': state}),
'info')
def __str__(self): def __str__(self):
return str(self.user) return str(self.user)

View File

@ -108,3 +108,10 @@ def assign_state_on_reactivate(sender, instance, *args, **kwargs):
# If we're saving a user and that user is in the Guest state, assume is_active was just set to True and assign state # If we're saving a user and that user is in the Guest state, assume is_active was just set to True and assign state
if instance.is_active and instance.profile.state == get_guest_state(): if instance.is_active and instance.profile.state == get_guest_state():
instance.profile.assign_state() instance.profile.assign_state()
@receiver(post_save, sender=EveCharacter)
def check_state_on_character_update(sender, instance, *args, **kwargs):
# if this is a main character updating, check that user's state
if instance.userprofile:
instance.userprofile.assign_state()

View File

@ -80,10 +80,6 @@
<div class="navbar-default sidebar auth-sidebar" role="navigation"> <div class="navbar-default sidebar auth-sidebar" role="navigation">
<div class="sidebar-nav navbar-collapse"> <div class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu"> <ul class="nav" id="side-menu">
<li class="text-center divider-horizontal">
<h5>{% trans "Main Navigation" %}</h5>
</li>
<li> <li>
<a class="{% navactive request 'authentication:dashboard' %}" href="{% url 'authentication:dashboard' %}"> <a class="{% navactive request 'authentication:dashboard' %}" href="{% url 'authentication:dashboard' %}">
<i class="fa fa-dashboard fa-fw grayiconecolor"></i>{% trans " Dashboard" %} <i class="fa fa-dashboard fa-fw grayiconecolor"></i>{% trans " Dashboard" %}
@ -101,9 +97,6 @@
</li> </li>
{% menu_main %} {% menu_main %}
<li class="text-center divider-horizontal">
<h5>{% trans "Aux Navigation" %}</h5>
</li>
<li> <li>
<a class="{% navactive request 'auth_services' %}" href="{% url 'auth_services' %}"> <a class="{% navactive request 'auth_services' %}" href="{% url 'auth_services' %}">

View File

@ -4,6 +4,6 @@ If this was you, please go to the following URL to confirm your email address:
{{ url }} {{ url }}
This link will expire in {{ expiration_days }} day{{ plural }}. This link will expire in {{ expiration_days }} day(s).
If this was not you, it is safe to ignore this email. If this was not you, it is safe to ignore this email.

View File

@ -10,7 +10,7 @@ urlpatterns = [
url(r'^account/login/$', TemplateView.as_view(template_name='public/login.html'), name='login'), url(r'^account/login/$', TemplateView.as_view(template_name='public/login.html'), name='login'),
url(r'^account/characters/main/$', views.main_character_change, name='change_main_character'), url(r'^account/characters/main/$', views.main_character_change, name='change_main_character'),
url(r'^account/characters/add/$', views.add_character, name='add_character'), url(r'^account/characters/add/$', views.add_character, name='add_character'),
url(r'^help/$', login_required(TemplateView.as_view(template_name='public/help.html')), name='help'), url(r'^help/$', login_required(TemplateView.as_view(template_name='registered/help.html')), name='help'),
url(r'^dashboard/$', url(r'^dashboard/$',
login_required(TemplateView.as_view(template_name='authentication/dashboard.html')), name='dashboard'), login_required(TemplateView.as_view(template_name='authentication/dashboard.html')), name='dashboard'),
] ]

View File

@ -110,8 +110,6 @@ class RegistrationView(BaseRegistrationView):
def get_email_context(self, activation_key): def get_email_context(self, activation_key):
context = super(RegistrationView, self).get_email_context(activation_key) context = super(RegistrationView, self).get_email_context(activation_key)
context['url'] = context['site'].domain + reverse('registration_activate', args=[activation_key]) context['url'] = context['site'].domain + reverse('registration_activate', args=[activation_key])
context['plural'] = 's' if context['expiration_days'] > 1 else '',
print(context)
return context return context

View File

@ -25,7 +25,7 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<b>{% trans "API Index: " %}</b> {{ corpstats.total_users }} Main Character{{ corpstats.total_users|pluralize }} <b>{% trans "Registration Index: " %}</b> {{ corpstats.total_users }} Main Character{{ corpstats.total_users|pluralize }}
<div class="progress"> <div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="{{ corpstats.registered_members }}" aria-valuemin="0" aria-valuemax="{{ corpstats.total_members }}" style="width: {% widthratio corpstats.registered_members corpstats.total_members 100 %}%;"> <div class="progress-bar" role="progressbar" aria-valuenow="{{ corpstats.registered_members }}" aria-valuemin="0" aria-valuemax="{{ corpstats.total_members }}" style="width: {% widthratio corpstats.registered_members corpstats.total_members 100 %}%;">
{{ corpstats.registered_members }}/{{ corpstats.total_members }} {{ corpstats.registered_members }}/{{ corpstats.total_members }}

View File

@ -81,6 +81,12 @@ def corpstats_view(request, corp_id=None):
# get default model if none requested # get default model if none requested
if not corp_id and available.count() == 1: if not corp_id and available.count() == 1:
corpstats = available[0] corpstats = available[0]
elif available.count() > 1 and request.user.profile.main_character:
# get their main corp if available
try:
corpstats = available.get(corp__corporation_id=request.user.profile.main_character.corporation_id)
except CorpStats.DoesNotExist:
pass
context = { context = {
'available': available, 'available': available,

View File

@ -31,9 +31,9 @@ This bar contains a dropdown menu of all available corps. If the user has the `a
On the right of this bar is a search field. Press enter to search. It checks all characters in all Corp Stats you have view permission to and returns search results. Generic searches (such as 'a') will be slow. On the right of this bar is a search field. Press enter to search. It checks all characters in all Corp Stats you have view permission to and returns search results. Generic searches (such as 'a') will be slow.
### API Index ### Registration Index
![API Index](/_static/images/features/corpstats/api_index.png) ![Registration Index](/_static/images/features/corpstats/api_index.png)
This is a visual indication of the number of registered characters. This is a visual indication of the number of registered characters.
@ -41,9 +41,9 @@ This is a visual indication of the number of registered characters.
![last update and update button](/_static/images/features/corpstats/last_update.png) ![last update and update button](/_static/images/features/corpstats/last_update.png)
Corp Stats do not automatically update. They update once upon creation for initial data, and whenever someone presses the update button. Corp Stats automatically update every 6 hours. An update can be performed immediately by pressing thi update button.
Only superusers and the creator of the Corp Stat can update it. Only superusers and the creator of the Corp Stat can trigger an immediate update.
### Member List ### Member List

View File

@ -4,15 +4,6 @@ from optimer.models import OpTimer
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
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): class FatlinkForm(forms.Form):
fatname = forms.CharField(label=_('Name of fat-link'), required=True) 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, duration = forms.IntegerField(label=_("Duration of fat-link"), required=True, initial=30, min_value=1,

View File

@ -10,5 +10,9 @@ from hrapplications.models import ApplicationComment
admin.site.register(Application) admin.site.register(Application)
admin.site.register(ApplicationComment) admin.site.register(ApplicationComment)
admin.site.register(ApplicationQuestion) admin.site.register(ApplicationQuestion)
admin.site.register(ApplicationForm)
admin.site.register(ApplicationResponse) admin.site.register(ApplicationResponse)
@admin.register(ApplicationForm)
class ApplicationFormAdmin(admin.ModelAdmin):
filter_horizontal = ['questions']

View File

@ -49,7 +49,7 @@ class Application(models.Model):
@property @property
def characters(self): def characters(self):
return EveCharacter.objects.filter(user=self.user) return [o.character for o in self.user.character_ownerships.all()]
@property @property
def reviewer_str(self): def reviewer_str(self):

View File

@ -23,5 +23,4 @@ class OpTimer(models.Model):
eve_character = models.ForeignKey(EveCharacter) eve_character = models.ForeignKey(EveCharacter)
def __str__(self): def __str__(self):
output = self.operation_name return self.operation_name
return output.encode('utf-8')

View File

@ -5,7 +5,7 @@ dnspython
passlib passlib
requests>=2.9.1 requests>=2.9.1
bcrypt bcrypt
slugify python-slugify>=1.2
requests-oauthlib requests-oauthlib
sleekxmpp sleekxmpp
redis redis

View File

@ -14,6 +14,7 @@ from srp.managers import SRPManager
from notifications import notify from notifications import notify
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.contrib.humanize.templatetags.humanize import intcomma
import uuid import uuid
import logging import logging
@ -56,7 +57,7 @@ def srp_fleet_view(request, fleet_id):
fleet_main = get_object_or_404(SrpFleetMain, id=fleet_id) fleet_main = get_object_or_404(SrpFleetMain, id=fleet_id)
context = {"fleet_id": fleet_id, "fleet_status": fleet_main.fleet_srp_status, context = {"fleet_id": fleet_id, "fleet_status": fleet_main.fleet_srp_status,
"srpfleetrequests": fleet_main.srpuserrequest_set.all(), "srpfleetrequests": fleet_main.srpuserrequest_set.all(),
"totalcost": fleet_main.total_cost} "totalcost": fleet_main.total_cost}
return render(request, 'registered/srpfleetdata.html', context=context) return render(request, 'registered/srpfleetdata.html', context=context)
@ -138,7 +139,8 @@ def srp_fleet_mark_completed(request, fleet_id):
srpfleetmain.fleet_srp_status = "Completed" srpfleetmain.fleet_srp_status = "Completed"
srpfleetmain.save() srpfleetmain.save()
logger.info("Marked SRP Fleet %s as completed by user %s" % (srpfleetmain.fleet_name, request.user)) logger.info("Marked SRP Fleet %s as completed by user %s" % (srpfleetmain.fleet_name, request.user))
messages.success(request, _('Marked SRP fleet %(fleetname)s as completed.') % {"fleetname": srpfleetmain.fleet_name}) messages.success(request,
_('Marked SRP fleet %(fleetname)s as completed.') % {"fleetname": srpfleetmain.fleet_name})
return redirect("auth_srp_fleet_view", fleet_id) return redirect("auth_srp_fleet_view", fleet_id)
@ -150,7 +152,8 @@ def srp_fleet_mark_uncompleted(request, fleet_id):
srpfleetmain.fleet_srp_status = "" srpfleetmain.fleet_srp_status = ""
srpfleetmain.save() srpfleetmain.save()
logger.info("Marked SRP Fleet %s as incomplete for user %s" % (fleet_id, request.user)) logger.info("Marked SRP Fleet %s as incomplete for user %s" % (fleet_id, request.user))
messages.success(request, _('Marked SRP fleet %(fleetname)s as incomplete.') % {"fleetname": srpfleetmain.fleet_name}) messages.success(request,
_('Marked SRP fleet %(fleetname)s as incomplete.') % {"fleetname": srpfleetmain.fleet_name})
return redirect("auth_srp_fleet_view", fleet_id) return redirect("auth_srp_fleet_view", fleet_id)
@ -158,12 +161,10 @@ def srp_fleet_mark_uncompleted(request, fleet_id):
@permission_required('srp.access_srp') @permission_required('srp.access_srp')
def srp_request_view(request, fleet_srp): def srp_request_view(request, fleet_srp):
logger.debug("srp_request_view called by user %s for fleet srp code %s" % (request.user, fleet_srp)) logger.debug("srp_request_view called by user %s for fleet srp code %s" % (request.user, fleet_srp))
completed = False
no_srp_code = False
if SrpFleetMain.objects.filter(fleet_srp_code=fleet_srp).exists() is False: if SrpFleetMain.objects.filter(fleet_srp_code=fleet_srp).exists() is False:
no_srp_code = True messages.error(request, _("Unable to locate SRP Fleet using code %(code)s") % fleet_srp)
logger.error("Unable to locate SRP Fleet using code %s for user %s" % (fleet_srp, request.user)) return redirect(srp_management)
if request.method == 'POST': if request.method == 'POST':
form = SrpFleetUserRequestForm(request.POST) form = SrpFleetUserRequestForm(request.POST)
@ -188,7 +189,8 @@ def srp_request_view(request, fleet_srp):
request.user, srp_request.killboard_link)) request.user, srp_request.killboard_link))
# THIS SHOULD BE IN FORM VALIDATION # THIS SHOULD BE IN FORM VALIDATION
messages.error(request, messages.error(request,
_("Your SRP request Killmail link is invalid. Please make sure you are using zKillboard.")) _(
"Your SRP request Killmail link is invalid. Please make sure you are using zKillboard."))
return redirect("auth_srp_management_view") return redirect("auth_srp_management_view")
srp_ship_name = EveManager.get_itemtype(ship_type_id).name srp_ship_name = EveManager.get_itemtype(ship_type_id).name
srp_request.srp_ship_name = srp_ship_name srp_request.srp_ship_name = srp_ship_name
@ -196,16 +198,16 @@ def srp_request_view(request, fleet_srp):
srp_request.kb_total_loss = kb_total_loss srp_request.kb_total_loss = kb_total_loss
srp_request.post_time = post_time srp_request.post_time = post_time
srp_request.save() srp_request.save()
completed = True
logger.info("Created SRP Request on behalf of user %s for fleet name %s" % ( logger.info("Created SRP Request on behalf of user %s for fleet name %s" % (
request.user, srp_fleet_main.fleet_name)) request.user, srp_fleet_main.fleet_name))
messages.success(request, _('Submitted SRP request for your %(ship)s.') % {"ship": srp_ship_name}) messages.success(request, _('Submitted SRP request for your %(ship)s.') % {"ship": srp_ship_name})
return redirect(srp_management)
else: else:
logger.debug("Returning blank SrpFleetUserRequestForm") logger.debug("Returning blank SrpFleetUserRequestForm")
form = SrpFleetUserRequestForm() form = SrpFleetUserRequestForm()
render_items = {'form': form, "completed": completed, "no_srp_code": no_srp_code} render_items = {'form': form}
return render(request, 'registered/srpfleetrequest.html', context=render_items) return render(request, 'registered/srpfleetrequest.html', context=render_items)
@ -219,7 +221,7 @@ def srp_request_remove(request, srp_request_id):
srpuserrequest.delete() srpuserrequest.delete()
logger.info("Deleted SRP request id %s for user %s" % (srp_request_id, request.user)) logger.info("Deleted SRP request id %s for user %s" % (srp_request_id, request.user))
messages.success(request, _('Deleted SRP request from %(character)s for their %(ship)s.') % { messages.success(request, _('Deleted SRP request from %(character)s for their %(ship)s.') % {
"character": srpuserrequest.character, "ship": srpuserrequest.srp_ship_name}) "character": srpuserrequest.character, "ship": srpuserrequest.srp_ship_name})
return redirect("auth_srp_fleet_view", srpuserrequest.srp_fleet_main.id) return redirect("auth_srp_fleet_view", srpuserrequest.srp_fleet_main.id)
@ -236,13 +238,15 @@ def srp_request_approve(request, srp_request_id):
srp_request_id, srpuserrequest.character, request.user)) srp_request_id, srpuserrequest.character, request.user))
messages.success(request, _('Approved SRP request from %(character)s for their %(ship)s.') % { messages.success(request, _('Approved SRP request from %(character)s for their %(ship)s.') % {
"character": srpuserrequest.character, "ship": srpuserrequest.srp_ship_name}) "character": srpuserrequest.character, "ship": srpuserrequest.srp_ship_name})
notify( if srpuserrequest.character.userprofile:
srpuserrequest.character.user, notify(
'SRP Request Approved', srpuserrequest.character.userprofile.user,
level='success', 'SRP Request Approved',
message='Your SRP request for a %s lost during %s has been approved for %s ISK.' % ( level='success',
srpuserrequest.srp_ship_name, srpuserrequest.srp_fleet_main.fleet_name, srpuserrequest.srp_total_amount) message='Your SRP request for a %s lost during %s has been approved for %s ISK.' % (
) srpuserrequest.srp_ship_name, srpuserrequest.srp_fleet_main.fleet_name,
intcomma(srpuserrequest.srp_total_amount))
)
return redirect("auth_srp_fleet_view", srpuserrequest.srp_fleet_main.id) return redirect("auth_srp_fleet_view", srpuserrequest.srp_fleet_main.id)
@ -257,13 +261,14 @@ def srp_request_reject(request, srp_request_id):
srp_request_id, srpuserrequest.character, request.user)) srp_request_id, srpuserrequest.character, request.user))
messages.success(request, _('Rejected SRP request from %(character)s for their %(ship)s.') % { messages.success(request, _('Rejected SRP request from %(character)s for their %(ship)s.') % {
"character": srpuserrequest.character, "ship": srpuserrequest.srp_ship_name}) "character": srpuserrequest.character, "ship": srpuserrequest.srp_ship_name})
notify( if srpuserrequest.character.userprofile:
srpuserrequest.character.user, notify(
'SRP Request Rejected', srpuserrequest.character.userprofile.user,
level='danger', 'SRP Request Rejected',
message='Your SRP request for a %s lost during %s has been rejected.' % ( level='danger',
srpuserrequest.srp_ship_name, srpuserrequest.srp_fleet_main.fleet_name) message='Your SRP request for a %s lost during %s has been rejected.' % (
) srpuserrequest.srp_ship_name, srpuserrequest.srp_fleet_main.fleet_name)
)
return redirect("auth_srp_fleet_view", srpuserrequest.srp_fleet_main.id) return redirect("auth_srp_fleet_view", srpuserrequest.srp_fleet_main.id)
@ -281,12 +286,12 @@ def srp_request_update_amount_view(request, fleet_srp_request_id):
srp_request.srp_total_amount = form.cleaned_data['srp_total_amount'] srp_request.srp_total_amount = form.cleaned_data['srp_total_amount']
srp_request.save() srp_request.save()
logger.info("Updated srp request id %s total to %s by user %s" % ( logger.info("Updated srp request id %s total to %s by user %s" % (
fleet_srp_request_id, form.cleaned_data['srp_total_amount'], request.user)) fleet_srp_request_id, intcomma(form.cleaned_data['srp_total_amount']), request.user))
messages.success(request, _('Updated SRP amount.')) messages.success(request, _('Updated SRP amount.'))
return redirect("auth_srp_fleet_view", srp_request.srp_fleet_main.id) return redirect("auth_srp_fleet_view", srp_request.srp_fleet_main.id)
else: else:
logger.debug("Returning blank SrpFleetUpdateCostForm") logger.debug("Returning blank SrpFleetUpdateCostForm")
form = SrpFleetUpdateCostForm() form = SrpFleetUpdateCostForm(initial={'srp_total_amount': srp_request.srp_total_amount or srp_request.kb_total_loss})
render_items = {'form': form} render_items = {'form': form}
@ -305,9 +310,10 @@ def srp_fleet_edit_view(request, fleet_id):
srpfleetmain.fleet_srp_aar_link = form.cleaned_data['fleet_aar_link'] srpfleetmain.fleet_srp_aar_link = form.cleaned_data['fleet_aar_link']
srpfleetmain.save() srpfleetmain.save()
logger.info("User %s edited SRP Fleet %s" % (request.user, srpfleetmain.fleet_name)) logger.info("User %s edited SRP Fleet %s" % (request.user, srpfleetmain.fleet_name))
messages.success(request, _('Saved changes to SRP fleet %(fleetname)s') % {"fleetname": srpfleetmain.fleet_name}) messages.success(request,
_('Saved changes to SRP fleet %(fleetname)s') % {"fleetname": srpfleetmain.fleet_name})
return redirect("auth_srp_management_view") return redirect("auth_srp_management_view")
else: else:
logger.debug("Returning blank SrpFleetMainUpdateForm") logger.debug("Returning blank SrpFleetMainUpdateForm")
form = SrpFleetMainUpdateForm() form = SrpFleetMainUpdateForm()
return render(request, 'registered/srpfleetupdate.html', context={'form': form}) return render(request, 'registered/srpfleetupdate.html', context={'form': form})

View File

@ -9,13 +9,14 @@
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<br>
{% include 'registered/groupmanagementmenu.html' %} {% include 'registered/groupmanagementmenu.html' %}
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#add">{% trans "Group Add Requests" %}</a></li> <li class="active"><a data-toggle="tab" href="#add">{% trans "Group Add Requests" %}</a></li>
<li><a data-toggle="tab" href="#leave">{% trans "Group Leave Requests" %}</a></li> <li><a data-toggle="tab" href="#leave">{% trans "Group Leave Requests" %}</a></li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div id="add" class="tab-pane fade in active"> <div id="add" class="tab-pane fade in active panel panel-default">
<div class="panel-body"> <div class="panel-body">
{% if acceptrequests %} {% if acceptrequests %}
<table class="table"> <table class="table">
@ -46,7 +47,7 @@
{% endif %} {% endif %}
</div> </div>
</div> </div>
<div id="leave" class="tab-pane fade"> <div id="leave" class="tab-pane fade panel panel-default">
<div class="panel-body"> <div class="panel-body">
{% if leaverequests %} {% if leaverequests %}
<table class="table"> <table class="table">

View File

@ -9,6 +9,7 @@
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<br>
{% include 'registered/groupmanagementmenu.html' %} {% include 'registered/groupmanagementmenu.html' %}
<h3>{{ group.name }} {% trans 'Members' %}</h3> <h3>{{ group.name }} {% trans 'Members' %}</h3>
<div id="list" class=""> <div id="list" class="">

View File

@ -9,6 +9,7 @@
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<br>
{% include 'registered/groupmanagementmenu.html' %} {% include 'registered/groupmanagementmenu.html' %}
<div> <div>
{% if groups %} {% if groups %}

View File

@ -10,13 +10,10 @@
<h1 class="page-header text-center">Help</h1> <h1 class="page-header text-center">Help</h1>
<div class="container-fluid"> <div class="container-fluid">
<div class="col-md-4 col-md-offset-4"> <div class="embed-responsive embed-responsive-16by9">
<div class="row"> <iframe class="embed-responsive-item" src="https://allianceauth.readthedocs.io/en/latest/features/"></iframe>
<p class="text-center">
Contact IT
</p>
</div>
</div> </div>
</div> </div>
</div> </div>
{% endblock content %} {% endblock content %}

View File

@ -10,52 +10,56 @@
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
{% if not STATE == MEMBER_STATE %} <h1 class="page-header text-center">{% trans "Personal Applications" %}
<h1 class="page-header text-center">{% trans "Personal Applications" %} <div class="text-right">
<div class="text-right"> {% if create %}
{% if create %} <a href="{% url 'auth_hrapplication_create_view' %}">
<a href="{% url 'auth_hrapplication_create_view' %}"><button type="button" class="btn btn-success">{% trans "Create Application" %}</button></a> <button type="button" class="btn btn-success">{% trans "Create Application" %}</button>
{% else %} </a>
<button type="button" class="btn btn-success" disabled>{% trans "Create Application" %}</button> {% else %}
{% endif %} <button type="button" class="btn btn-success" disabled>{% trans "Create Application" %}</button>
</div> {% endif %}
</h1> </div>
{% if personal_apps %} </h1>
<table class="table table-condensed"> {% if personal_apps %}
<tr> <div class="panel panel-default">
<th class="text-center">{% trans "Username" %}</th> <table class="table table-condensed">
<th class="text-center">{% trans "Corporation" %}
<th class="text-center">{% trans "Status" %}</th>
<th class="text-center">{% trans "Actions" %}</th>
</tr>
{% for personal_app in personal_apps %}
<tr> <tr>
<td class="text-center">{{ personal_app.user.username }}</td> <th class="text-center">{% trans "Username" %}</th>
<td class="text-center">{{ personal_app.form.corp.corporation_name }}</td> <th class="text-center">{% trans "Corporation" %}
<td class="text-center"> <th class="text-center">{% trans "Status" %}</th>
{% if personal_app.approved == None %} <th class="text-center">{% trans "Actions" %}</th>
<div class="label label-warning">{% trans "Pending" %}</div>
{% elif personal_app.approved == True %}
<div class="label label-success">{% trans "Approved" %}</div>
{% else %}
<div class="label label-danger">{% trans "Rejected" %}</div>
{% endif %}
</td>
<td class="text-center">
<a href="{% url 'auth_hrapplication_personal_view' personal_app.id %}"class="btn btn-primary">
<span class="glyphicon glyphicon-eye-open"></span>
</a>
{% if personal_app.approved == None %}
<a href="{% url 'auth_hrapplication_personal_removal' personal_app.id %}" class="btn btn-danger">
<span class="glyphicon glyphicon-remove"></span>
</a>
{% endif %}
</td>
</tr> </tr>
{% endfor %} {% for personal_app in personal_apps %}
</table> <tr>
{% endif %} <td class="text-center">{{ personal_app.user.username }}</td>
<td class="text-center">{{ personal_app.form.corp.corporation_name }}</td>
<td class="text-center">
{% if personal_app.approved == None %}
<div class="label label-warning">{% trans "Pending" %}</div>
{% elif personal_app.approved == True %}
<div class="label label-success">{% trans "Approved" %}</div>
{% else %}
<div class="label label-danger">{% trans "Rejected" %}</div>
{% endif %}
</td>
<td class="text-center">
<a href="{% url 'auth_hrapplication_personal_view' personal_app.id %}"
class="btn btn-primary">
<span class="glyphicon glyphicon-eye-open"></span>
</a>
{% if personal_app.approved == None %}
<a href="{% url 'auth_hrapplication_personal_removal' personal_app.id %}"
class="btn btn-danger">
<span class="glyphicon glyphicon-remove"></span>
</a>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>
{% endif %} {% endif %}
{% if perms.auth.human_resources %} {% if perms.auth.human_resources %}
<h1 class="page-header text-center">{% trans "Application Management" %} <h1 class="page-header text-center">{% trans "Application Management" %}
@ -71,91 +75,93 @@
<li><a data-toggle="tab" href="#reviewed">{% trans "Reviewed" %}</a></li> <li><a data-toggle="tab" href="#reviewed">{% trans "Reviewed" %}</a></li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div id="pending" class="tab-pane fade in active"> <div id="pending" class="tab-pane fade in active panel panel-default">
<div class="panel-body"> <div class="panel-body">
{% if applications %} {% if applications %}
<table class="table"> <table class="table">
<tr>
<th class="text-center">{% trans "Date" %}</th>
<th class="text-center">{% trans "Username" %}</th>
<th class="text-center">{% trans "Main Character" %}</th>
<th class="text-center">{% trans "Corporation" %}</th>
<th class="text-center">{% trans "Status" %}</th>
<th class="text-center">{% trans "Actions" %}</th>
</tr>
{% for app in applications %}
<tr> <tr>
<td class="text-center">{{ app.created }}</td> <th class="text-center">{% trans "Date" %}</th>
<td class="text-center">{{ app.user.username }}</td> <th class="text-center">{% trans "Username" %}</th>
<td class="text-center">{{ app.main_character }}</td> <th class="text-center">{% trans "Main Character" %}</th>
<td class="text-center">{{ app.form.corp.corporation_name }}</td> <th class="text-center">{% trans "Corporation" %}</th>
<td class="text-center"> <th class="text-center">{% trans "Status" %}</th>
{% if app.approved == None %} <th class="text-center">{% trans "Actions" %}</th>
{% if app.reviewer_str %}
<div class="label label-info">{% trans "Reviewer:" %} {{ app.reviewer_str }}</div>
{% else %}
<div class="label label-warning">{% trans "Pending" %}</div>
{% endif %}
{% elif app.approved == True %}
<div class="label label-success">{% trans "Approved" %}</div>
{% else %}
<div class="label label-danger">{% trans "Rejected" %}</div>
{% endif %}
</td>
<td class="text-center">
<a href="{% url 'auth_hrapplication_view' app.id %}" class="btn btn-primary">
<span class="glyphicon glyphicon-eye-open"></span>
</a>
</td>
</tr> </tr>
{% endfor %} {% for app in applications %}
</table> <tr>
<td class="text-center">{{ app.created }}</td>
<td class="text-center">{{ app.user.username }}</td>
<td class="text-center">{{ app.main_character }}</td>
<td class="text-center">{{ app.form.corp.corporation_name }}</td>
<td class="text-center">
{% if app.approved == None %}
{% if app.reviewer_str %}
<div class="label label-info">{% trans "Reviewer:" %} {{ app.reviewer_str }}</div>
{% else %}
<div class="label label-warning">{% trans "Pending" %}</div>
{% endif %}
{% elif app.approved == True %}
<div class="label label-success">{% trans "Approved" %}</div>
{% else %}
<div class="label label-danger">{% trans "Rejected" %}</div>
{% endif %}
</td>
<td class="text-center">
<a href="{% url 'auth_hrapplication_view' app.id %}"
class="btn btn-primary">
<span class="glyphicon glyphicon-eye-open"></span>
</a>
</td>
</tr>
{% endfor %}
</table>
{% else %} {% else %}
<div class="alert alert-warning text-center">{% trans "No pending applications." %}</div> <div class="alert alert-warning text-center">{% trans "No pending applications." %}</div>
{% endif %} {% endif %}
</div> </div>
</div> </div>
<div id="reviewed" class="tab-pane fade"> <div id="reviewed" class="tab-pane fade panel panel-default">
<div class="panel-body"> <div class="panel-body">
{% if finished_applications %} {% if finished_applications %}
<table class="table"> <table class="table">
<tr>
<th class="text-center">{% trans "Date" %}</th>
<th class="text-center">{% trans "Username" %}</th>
<th class="text-center">{% trans "Main Character" %}</th>
<th class="text-center">{% trans "Corporation" %}</th>
<th class="text-center">{% trans "Status" %}</th>
<th class="text-center">{% trans "Actions" %}</th>
</tr>
{% for app in finished_applications %}
<tr> <tr>
<td class="text-center">{{ app.created }}</td> <th class="text-center">{% trans "Date" %}</th>
<td class="text-center">{{ app.user.username }}</td> <th class="text-center">{% trans "Username" %}</th>
<td class="text-center">{{ app.main_character }}</td> <th class="text-center">{% trans "Main Character" %}</th>
<td class="text-center">{{ app.form.corp.corporation_name }}</td> <th class="text-center">{% trans "Corporation" %}</th>
<td class="text-center"> <th class="text-center">{% trans "Status" %}</th>
{% if app.approved == None %} <th class="text-center">{% trans "Actions" %}</th>
{% if app.reviewer_str %}
<div class="label label-info">{% trans "Reviewer:" %} {{ app.reviewer_str }}</div>
{% else %}
<div class="label label-warning">{% trans "Pending" %}</div>
{% endif %}
{% elif app.approved == True %}
<div class="label label-success">{% trans "Approved" %}</div>
{% else %}
<div class="label label-danger">{% trans "Rejected" %}</div>
{% endif %}
</td>
<td class="text-center">
<a href="{% url 'auth_hrapplication_view' app.id %}" class="btn btn-primary">
<span class="glyphicon glyphicon-eye-open"></span>
</a>
</td>
</tr> </tr>
{% endfor %} {% for app in finished_applications %}
</table> <tr>
<td class="text-center">{{ app.created }}</td>
<td class="text-center">{{ app.user.username }}</td>
<td class="text-center">{{ app.main_character }}</td>
<td class="text-center">{{ app.form.corp.corporation_name }}</td>
<td class="text-center">
{% if app.approved == None %}
{% if app.reviewer_str %}
<div class="label label-info">{% trans "Reviewer:" %} {{ app.reviewer_str }}</div>
{% else %}
<div class="label label-warning">{% trans "Pending" %}</div>
{% endif %}
{% elif app.approved == True %}
<div class="label label-success">{% trans "Approved" %}</div>
{% else %}
<div class="label label-danger">{% trans "Rejected" %}</div>
{% endif %}
</td>
<td class="text-center">
<a href="{% url 'auth_hrapplication_view' app.id %}"
class="btn btn-primary">
<span class="glyphicon glyphicon-eye-open"></span>
</a>
</td>
</tr>
{% endfor %}
</table>
{% else %} {% else %}
<div class="alert alert-warning text-center">{% trans "No reviewed applications." %}</div> <div class="alert alert-warning text-center">{% trans "No reviewed applications." %}</div>
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@ -75,29 +75,31 @@
<div class="row"> <div class="row">
<div class="panel panel-primary"> <div class="panel panel-primary">
<div class="panel-heading">{% trans "Actions" %}</div> <div class="panel-heading">{% trans "Actions" %}</div>
{% if app.approved == None %} <div class="panel-body text-center">
{% if app.reviewer == user %} {% if app.approved == None %}
{% if perms.hrapplications.approve_application %} {% if app.reviewer == user %}
<a href="{% url 'auth_hrapplication_approve' app.id %}" {% if perms.hrapplications.approve_application %}
class="btn btn-success">{% trans "Approve" %}</a> <a href="{% url 'auth_hrapplication_approve' app.id %}"
class="btn btn-success">{% trans "Approve" %}</a>
{% endif %}
{% if perms.hrapplications.reject_application %}
<a href="{% url 'auth_hrapplication_reject' app.id %}"
class="btn btn-danger">{% trans "Reject" %}</a>
{% endif %}
{% if perms.hrapplications.delete_application %}
<a href="{% url 'auth_hrapplication_remove' app.id %}"
class="btn btn-danger">{% trans "Delete" %}</a>
{% endif %}
{% elif not app.reviewer %}
<a href="{% url 'auth_hrapplication_mark_in_progress' app.id %}"
class="btn btn-warning">{% trans "Mark in Progress" %}</a>
{% endif %} {% endif %}
{% if perms.hrapplications.reject_application %}
<a href="{% url 'auth_hrapplication_reject' app.id %}"
class="btn btn-danger">{% trans "Reject" %}</a>
{% endif %}
{% if perms.hrapplications.delete_application %}
<a href="{% url 'auth_hrapplication_remove' app.id %}"
class="btn btn-danger">{% trans "Delete" %}</a>
{% endif %}
{% elif not app.reviewer %}
<a href="{% url 'auth_hrapplication_mark_in_progress' app.id %}"
class="btn btn-warning">{% trans "Mark in Progress" %}</a>
{% endif %} {% endif %}
{% endif %} {% if perms.hrapplications.add_applicationcomment %}
{% if perms.hrapplications.add_applicationcomment %} <button type="button" class="btn btn-primary" data-toggle="modal"
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">{% trans "Comment" %}</button>
data-target="#myModal">{% trans "Comment" %}</button> {% endif %}
{% endif %} </div>
</div> </div>
</div> </div>
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">

View File

@ -59,10 +59,10 @@
{% if perms.auth.optimer_management %} {% if perms.auth.optimer_management %}
<td style="width:150px" class="text-center">{{ ops.eve_character }}</td> <td style="width:150px" class="text-center">{{ ops.eve_character }}</td>
<td class="text-center"> <td class="text-center">
<a href="{% url 'auth_remove_optimer' ops.id %}" class="btn btn-danger"> <a href="{% url 'auth_remove_optimer' ops.id %}" class="btn btn-danger" title="{% trans 'Delete' %}">
<span class="glyphicon glyphicon-remove"></span> <span class="glyphicon glyphicon-remove"></span>
</a> </a>
<a href="{% url 'auth_edit_optimer' ops.id %}" class="btn btn-info"> <a href="{% url 'auth_edit_optimer' ops.id %}" class="btn btn-info" title="{% trans 'Edit' %}">
<span class="glyphicon glyphicon-pencil"></span> <span class="glyphicon glyphicon-pencil"></span>
</a> </a>
</td> </td>

View File

@ -3,7 +3,7 @@
{% load staticfiles %} {% load staticfiles %}
{% load i18n %} {% load i18n %}
{% block title %}Alliance Auth - SRP Request{% endblock %} {% block title %}SRP Request{% endblock %}
{% block page_title %}{% trans "SRP Request" %}{% endblock page_title %} {% block page_title %}{% trans "SRP Request" %}{% endblock page_title %}
{% block extra_css %} {% block extra_css %}
@ -17,24 +17,13 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="col-md-4 col-md-offset-4"> <div class="col-md-4 col-md-offset-4">
<div class="row"> <div class="row">
{% if no_srp_code %} <form class="form-signin" role="form" action="" method="POST">
<div class="alert alert-danger" role="alert">{% trans "SRP Code Does Not Exist" %}</div> {% csrf_token %}
{% else %} {{ form|bootstrap }}
{% if completed == False %} <br/>
<form class="form-signin" role="form" action="" method="POST"> <button class="btn btn-lg btn-primary btn-block" type="submit">{% trans "Create SRP Request" %}
{% csrf_token %} </button>
{{ form|bootstrap }} </form>
<br/>
<button class="btn btn-lg btn-primary btn-block" type="submit">{% trans "Create SRP Request" %}
</button>
</form>
{% else %}
<div class="alert alert-success" role="alert">{% trans "SRP Request Successfully Submitted" %}</div>
<div class="text-center">
<a href="{% url 'auth_srp_management_view' %}" class="btn btn-primary btn-lg">{% trans 'Continue' %}</a>
</div>
{% endif %}
{% endif %}
</div> </div>
</div> </div>
</div> </div>