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 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 = [
'django.contrib.admin',
'django.contrib.auth',
@ -68,7 +43,7 @@ INSTALLED_APPS = [
'geelweb.django.navhelper',
'bootstrap_pagination',
# Services
# Services - comment out if not used
'services.modules.mumble',
'services.modules.discord',
'services.modules.discourse',
@ -83,6 +58,25 @@ INSTALLED_APPS = [
'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 = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
@ -137,20 +131,6 @@ TEMPLATES = [
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
# 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 = 'Alliance Auth'
#################
# EMAIL SETTINGS
#################
# 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_PORT - SMTP Server PORT
# 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
#################
DEFAULT_FROM_EMAIL = 'no-reply@example.com'
DOMAIN = 'https://example.com'
DOMAIN = 'example.com'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = ''
@ -255,13 +261,13 @@ ESI_SSO_CALLBACK_URL = ''
#################
# 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
# https://docs.djangoproject.com/en/1.10/topics/http/shortcuts/#redirect
# - url names eg 'authentication:dashboard'
# - relative urls eg '/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.
# 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']
ACCOUNT_ACTIVATION_DAYS = 1
#####################################################
##
## Service Configuration
##
#####################################################
#####################
# Alliance Market
#####################
@ -402,10 +414,8 @@ DISCOURSE_SSO_SECRET = ''
# IPS4 Configuration
#####################################
# IPS4_URL - Base URL of the IPS4 install (no trailing slash). Include http://
# IPS4_API_KEY - API key provided by IPS4
#####################################
IPS4_URL = ''
IPS4_API_KEY = ''
IPS4_DB = {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'alliance_ips4',
@ -452,9 +462,11 @@ FLEETUP_USER_ID = ''
FLEETUP_API_ID = ''
FLEETUP_GROUP_ID = ''
#####################################
# Logging Configuration
#####################################
#####################################################
##
## Logging Configuration
##
#####################################################
# Set log_file and console level to desired state:
# DEBUG - basically stack trace, explains every step
# INFO - model creation, deletion, updates, etc
@ -559,12 +571,22 @@ LOGGING = {
'level': 'DEBUG',
},
'django': {
'handlers': ['log_file', 'console', 'notifications'],
'handlers': ['log_file', 'console'],
'level': 'ERROR',
},
}
}
#####################################################
##
## Magic Block
##
#####################################################
# This block automagically inserts needed settings if
# certain services are installed.
# Don't touch.
#########################################
# Conditionally add databases only if configured
if 'services.modules.phpbb3' in INSTALLED_APPS:
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.utils.text import slugify
from django import forms
from django.db.models.signals import post_save
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 services.hooks import ServicesHook
from services.tasks import validate_services
def make_service_hooks_update_groups_action(service):
@ -92,6 +95,18 @@ class StateForm(forms.ModelForm):
class StateAdmin(admin.ModelAdmin):
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
def has_delete_permission(request, obj=None):
if obj == get_guest_state():
@ -99,4 +114,18 @@ class StateAdmin(admin.ModelAdmin):
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
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
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})
@ -196,11 +198,15 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=20, unique=True)),
('priority', models.IntegerField(unique=True)),
('public', models.BooleanField(default=False)),
('member_alliances', models.ManyToManyField(blank=True,to='eveonline.EveAllianceInfo')),
('member_characters', models.ManyToManyField(blank=True,to='eveonline.EveCharacter')),
('member_corporations', models.ManyToManyField(blank=True,to='eveonline.EveCorporationInfo')),
('priority', models.IntegerField(unique=True,
help_text="Users get assigned the state with the highest priority available to them.")),
('public', models.BooleanField(default=False, help_text="Make this state available to any character.")),
('member_alliances', models.ManyToManyField(blank=True, to='eveonline.EveAllianceInfo',
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')),
],
options={
@ -215,7 +221,8 @@ class Migration(migrations.Migration):
models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL,
to='eveonline.EveCharacter')),
('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',
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 authentication.managers import CharacterOwnershipManager, StateManager
from eveonline.models import EveCharacter, EveCorporationInfo, EveAllianceInfo
from notifications import notify
from django.utils.translation import ugettext_lazy as _
import logging
logger = logging.getLogger(__name__)
@ -13,12 +15,16 @@ logger = logging.getLogger(__name__)
class State(models.Model):
name = models.CharField(max_length=20, unique=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_corporations = models.ManyToManyField(EveCorporationInfo, blank=True)
member_alliances = models.ManyToManyField(EveAllianceInfo, blank=True)
public = models.BooleanField(default=False)
member_characters = models.ManyToManyField(EveCharacter, blank=True,
help_text="Characters to which this state is available.")
member_corporations = models.ManyToManyField(EveCorporationInfo, blank=True,
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()
@ -62,6 +68,9 @@ class UserProfile(models.Model):
if commit:
logger.info('Updating {} state to {}'.format(self.user, self.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):
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 instance.is_active and instance.profile.state == get_guest_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="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu">
<li class="text-center divider-horizontal">
<h5>{% trans "Main Navigation" %}</h5>
</li>
<li>
<a class="{% navactive request 'authentication:dashboard' %}" href="{% url 'authentication:dashboard' %}">
<i class="fa fa-dashboard fa-fw grayiconecolor"></i>{% trans " Dashboard" %}
@ -101,9 +97,6 @@
</li>
{% menu_main %}
<li class="text-center divider-horizontal">
<h5>{% trans "Aux Navigation" %}</h5>
</li>
<li>
<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 }}
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.

View File

@ -10,7 +10,7 @@ urlpatterns = [
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/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/$',
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):
context = super(RegistrationView, self).get_email_context(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

View File

@ -25,7 +25,7 @@
</div>
<div class="row">
<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-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 }}

View File

@ -81,6 +81,12 @@ def corpstats_view(request, corp_id=None):
# get default model if none requested
if not corp_id and available.count() == 1:
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 = {
'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.
### 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.
@ -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)
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

View File

@ -4,15 +4,6 @@ from optimer.models import OpTimer
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):
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,

View File

@ -10,5 +10,9 @@ from hrapplications.models import ApplicationComment
admin.site.register(Application)
admin.site.register(ApplicationComment)
admin.site.register(ApplicationQuestion)
admin.site.register(ApplicationForm)
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
def characters(self):
return EveCharacter.objects.filter(user=self.user)
return [o.character for o in self.user.character_ownerships.all()]
@property
def reviewer_str(self):

View File

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

View File

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

View File

@ -14,6 +14,7 @@ from srp.managers import SRPManager
from notifications import notify
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.contrib.humanize.templatetags.humanize import intcomma
import uuid
import logging
@ -56,7 +57,7 @@ def srp_fleet_view(request, fleet_id):
fleet_main = get_object_or_404(SrpFleetMain, id=fleet_id)
context = {"fleet_id": fleet_id, "fleet_status": fleet_main.fleet_srp_status,
"srpfleetrequests": fleet_main.srpuserrequest_set.all(),
"totalcost": fleet_main.total_cost}
"totalcost": fleet_main.total_cost}
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.save()
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)
@ -150,7 +152,8 @@ def srp_fleet_mark_uncompleted(request, fleet_id):
srpfleetmain.fleet_srp_status = ""
srpfleetmain.save()
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)
@ -158,12 +161,10 @@ def srp_fleet_mark_uncompleted(request, fleet_id):
@permission_required('srp.access_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))
completed = False
no_srp_code = False
if SrpFleetMain.objects.filter(fleet_srp_code=fleet_srp).exists() is False:
no_srp_code = True
logger.error("Unable to locate SRP Fleet using code %s for user %s" % (fleet_srp, request.user))
messages.error(request, _("Unable to locate SRP Fleet using code %(code)s") % fleet_srp)
return redirect(srp_management)
if request.method == 'POST':
form = SrpFleetUserRequestForm(request.POST)
@ -188,7 +189,8 @@ def srp_request_view(request, fleet_srp):
request.user, srp_request.killboard_link))
# THIS SHOULD BE IN FORM VALIDATION
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")
srp_ship_name = EveManager.get_itemtype(ship_type_id).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.post_time = post_time
srp_request.save()
completed = True
logger.info("Created SRP Request on behalf of user %s for fleet name %s" % (
request.user, srp_fleet_main.fleet_name))
messages.success(request, _('Submitted SRP request for your %(ship)s.') % {"ship": srp_ship_name})
return redirect(srp_management)
else:
logger.debug("Returning blank 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)
@ -219,7 +221,7 @@ def srp_request_remove(request, srp_request_id):
srpuserrequest.delete()
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.') % {
"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)
@ -236,13 +238,15 @@ def srp_request_approve(request, srp_request_id):
srp_request_id, srpuserrequest.character, request.user))
messages.success(request, _('Approved SRP request from %(character)s for their %(ship)s.') % {
"character": srpuserrequest.character, "ship": srpuserrequest.srp_ship_name})
notify(
srpuserrequest.character.user,
'SRP Request Approved',
level='success',
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, srpuserrequest.srp_total_amount)
)
if srpuserrequest.character.userprofile:
notify(
srpuserrequest.character.userprofile.user,
'SRP Request Approved',
level='success',
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)
@ -257,13 +261,14 @@ def srp_request_reject(request, srp_request_id):
srp_request_id, srpuserrequest.character, request.user))
messages.success(request, _('Rejected SRP request from %(character)s for their %(ship)s.') % {
"character": srpuserrequest.character, "ship": srpuserrequest.srp_ship_name})
notify(
srpuserrequest.character.user,
'SRP Request Rejected',
level='danger',
message='Your SRP request for a %s lost during %s has been rejected.' % (
srpuserrequest.srp_ship_name, srpuserrequest.srp_fleet_main.fleet_name)
)
if srpuserrequest.character.userprofile:
notify(
srpuserrequest.character.userprofile.user,
'SRP Request Rejected',
level='danger',
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)
@ -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.save()
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.'))
return redirect("auth_srp_fleet_view", srp_request.srp_fleet_main.id)
else:
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}
@ -305,7 +310,8 @@ def srp_fleet_edit_view(request, fleet_id):
srpfleetmain.fleet_srp_aar_link = form.cleaned_data['fleet_aar_link']
srpfleetmain.save()
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")
else:
logger.debug("Returning blank SrpFleetMainUpdateForm")

View File

@ -9,13 +9,14 @@
{% block content %}
<div class="col-lg-12">
<br>
{% include 'registered/groupmanagementmenu.html' %}
<ul class="nav nav-tabs">
<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>
</ul>
<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">
{% if acceptrequests %}
<table class="table">
@ -46,7 +47,7 @@
{% endif %}
</div>
</div>
<div id="leave" class="tab-pane fade">
<div id="leave" class="tab-pane fade panel panel-default">
<div class="panel-body">
{% if leaverequests %}
<table class="table">

View File

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

View File

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

View File

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

View File

@ -10,52 +10,56 @@
{% block content %}
<div class="col-lg-12">
{% if not STATE == MEMBER_STATE %}
<h1 class="page-header text-center">{% trans "Personal Applications" %}
<div class="text-right">
{% if create %}
<a href="{% url 'auth_hrapplication_create_view' %}"><button type="button" class="btn btn-success">{% trans "Create Application" %}</button></a>
{% else %}
<button type="button" class="btn btn-success" disabled>{% trans "Create Application" %}</button>
{% endif %}
</div>
</h1>
{% if personal_apps %}
<table class="table table-condensed">
<tr>
<th class="text-center">{% trans "Username" %}</th>
<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 %}
<h1 class="page-header text-center">{% trans "Personal Applications" %}
<div class="text-right">
{% if create %}
<a href="{% url 'auth_hrapplication_create_view' %}">
<button type="button" class="btn btn-success">{% trans "Create Application" %}</button>
</a>
{% else %}
<button type="button" class="btn btn-success" disabled>{% trans "Create Application" %}</button>
{% endif %}
</div>
</h1>
{% if personal_apps %}
<div class="panel panel-default">
<table class="table table-condensed">
<tr>
<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>
<th class="text-center">{% trans "Username" %}</th>
<th class="text-center">{% trans "Corporation" %}
<th class="text-center">{% trans "Status" %}</th>
<th class="text-center">{% trans "Actions" %}</th>
</tr>
{% endfor %}
</table>
{% endif %}
{% for personal_app in personal_apps %}
<tr>
<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 %}
{% if perms.auth.human_resources %}
<h1 class="page-header text-center">{% trans "Application Management" %}
@ -71,91 +75,93 @@
<li><a data-toggle="tab" href="#reviewed">{% trans "Reviewed" %}</a></li>
</ul>
<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">
{% if applications %}
<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 %}
<table class="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>
<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>
{% endfor %}
</table>
{% for app in applications %}
<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 %}
<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 %}
</div>
</div>
<div id="reviewed" class="tab-pane fade">
<div id="reviewed" class="tab-pane fade panel panel-default">
<div class="panel-body">
{% if finished_applications %}
<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 %}
<table class="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>
<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>
{% endfor %}
</table>
{% for app in finished_applications %}
<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 %}
<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 %}
</div>
</div>

View File

@ -75,29 +75,31 @@
<div class="row">
<div class="panel panel-primary">
<div class="panel-heading">{% trans "Actions" %}</div>
{% if app.approved == None %}
{% if app.reviewer == user %}
{% if perms.hrapplications.approve_application %}
<a href="{% url 'auth_hrapplication_approve' app.id %}"
class="btn btn-success">{% trans "Approve" %}</a>
<div class="panel-body text-center">
{% if app.approved == None %}
{% if app.reviewer == user %}
{% if perms.hrapplications.approve_application %}
<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 %}
{% 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.add_applicationcomment %}
<button type="button" class="btn btn-primary" data-toggle="modal"
data-target="#myModal">{% trans "Comment" %}</button>
{% endif %}
{% if perms.hrapplications.add_applicationcomment %}
<button type="button" class="btn btn-primary" data-toggle="modal"
data-target="#myModal">{% trans "Comment" %}</button>
{% endif %}
</div>
</div>
</div>
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">

View File

@ -59,10 +59,10 @@
{% if perms.auth.optimer_management %}
<td style="width:150px" class="text-center">{{ ops.eve_character }}</td>
<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>
</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>
</a>
</td>

View File

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