mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2026-02-11 09:36:24 +01:00
Adarnof's Little Things (#547)
* Port to Django 1.10 Initial migrations for current states of all models. Requires faking to retain data. Removed all references to render_to_response, replacing with render shortcut. Same for HttpResponseRedirect to render shortcut. Corrected notification signal import to wait for app registry to finish loading. * Correct typos from render conversion * Modify models to suppress Django field warnings * Script for automatic database conversion - fakes initial migrations to preserve data Include LOGIN_URL setting * Correct context processor import typo * Removed pathfinder support. Current pathfinder versions require SSO, not APIs added to database. Conditionally load additional database definitions only if services are enabled. Prevents errors when running auth without creating all possible databases. * Condense context processors * Include Django 1.10 installation in migrate script Remove syncdb/evolve, replace with migrate for update script * Replaced member/blue perms with user state system Removed sigtracker Initial migrations for default perms and groups Removed perm bootstrapping on first run * Clean up services list * Remove fleet fittings page * Provide action feedback via django messaging Display unread notification count Correct left navbar alignment * Stop storing service passwords. Provide them one time upon activation or reset. Closes #177 * Add group sync buttons to admin site Allow searcing of AuthServicesInfo models Display user main character * Correct button CSS to remove underlines on hover * Added bulk actions to notifications Altered notification default ordering * Centralize API key validation. Remove unused error count on API key model. Restructure API key refresh task to queue all keys per user and await completion. Closes #350 * Example configuration files for supervisor. Copy to /etc/supervisor/conf.d and restart to take effect. Closes #521 Closes #266 * Pre-save receiver for member/blue state switching Removed is_blue field Added link to admin site * Remove all hardcoded URLs from views and templates Correct missing render arguments Closes #540 * Correct celeryd process directory * Migration to automatically set user states. Runs instead of waiting for next API refresh cycle. Should make the transition much easier. * Verify service accounts accessible to member state * Restructure project to remove unnecessary apps. (celerytask, util, portal, registraion apps) Added workarounds for python 3 compatibility. * Correct python2 compatibility * Check services against state being changed to * Python3 compatibility fixes * Relocate x2bool py3 fix * SSO integration for logging in to existing accounts. * Add missing url names for fleetup reverse * Sanitize groupnames before syncing. * Correct trailing slash preventing url resolution * Alter group name sanitization to allow periods and hyphens * Correct state check on pre_save model for corp/alliance group assignment * Remove sigtracker table from old dbs to allow user deletion * Include missing celery configuration * Teamspeak error handling * Prevent celery worker deadlock on async group result wait * Correct active navbar links for translated urls. Correct corp status url resolution for some links. Remove DiscordAuthToken model.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
@@ -1,24 +1,28 @@
|
||||
from __future__ import unicode_literals
|
||||
from django.contrib import admin
|
||||
|
||||
from models import EveCharacter
|
||||
from models import EveApiKeyPair
|
||||
from models import EveAllianceInfo
|
||||
from models import EveCorporationInfo
|
||||
from authentication.managers import AuthServicesInfoManager
|
||||
from eveonline.models import EveCharacter
|
||||
from eveonline.models import EveApiKeyPair
|
||||
from eveonline.models import EveAllianceInfo
|
||||
from eveonline.models import EveCorporationInfo
|
||||
from authentication.models import AuthServicesInfo
|
||||
|
||||
admin.site.register(EveAllianceInfo)
|
||||
admin.site.register(EveCorporationInfo)
|
||||
|
||||
|
||||
class EveApiKeyPairAdmin(admin.ModelAdmin):
|
||||
search_fields = ['api_id', 'user__username']
|
||||
list_display = ['api_id', 'user']
|
||||
|
||||
|
||||
class EveCharacterAdmin(admin.ModelAdmin):
|
||||
search_fields = ['character_name', 'corporation_name', 'alliance_name', 'user__username', 'api_id']
|
||||
list_display = ('character_name', 'corporation_name', 'alliance_name', 'user', 'main_character')
|
||||
|
||||
def main_character(self, obj):
|
||||
auth = AuthServicesInfoManager.get_auth_service_info(obj.user)
|
||||
@staticmethod
|
||||
def main_character(obj):
|
||||
auth = AuthServicesInfo.objects.get_or_create(user=obj.user)[0]
|
||||
if auth and auth.main_char_id:
|
||||
try:
|
||||
return EveCharacter.objects.get(character_id=auth.main_char_id)
|
||||
@@ -26,5 +30,6 @@ class EveCharacterAdmin(admin.ModelAdmin):
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
admin.site.register(EveCharacter, EveCharacterAdmin)
|
||||
admin.site.register(EveApiKeyPair, EveApiKeyPairAdmin)
|
||||
|
||||
7
eveonline/apps.py
Normal file
7
eveonline/apps.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class EveonlineConfig(AppConfig):
|
||||
name = 'eveonline'
|
||||
@@ -1,23 +1,24 @@
|
||||
from __future__ import unicode_literals
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
|
||||
from services.managers.eve_api_manager import EveApiManager
|
||||
from eveonline.managers import EveManager
|
||||
from eveonline.models import EveCharacter
|
||||
import evelink
|
||||
|
||||
from celerytask.tasks import determine_membership_by_character
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class UpdateKeyForm(forms.Form):
|
||||
user_state = None
|
||||
|
||||
class UpdateKeyForm(forms.Form):
|
||||
api_id = forms.CharField(max_length=254, required=True, label="Key ID")
|
||||
api_key = forms.CharField(max_length=254, required=True, label="Verification Code")
|
||||
|
||||
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
super(UpdateKeyForm, self).__init__(*args, **kwargs)
|
||||
self.user = user
|
||||
|
||||
def clean_api_id(self):
|
||||
try:
|
||||
api_id = int(self.cleaned_data['api_id'])
|
||||
@@ -28,38 +29,21 @@ class UpdateKeyForm(forms.Form):
|
||||
def clean(self):
|
||||
super(UpdateKeyForm, self).clean()
|
||||
|
||||
if 'api_id' in self.cleaned_data and 'api_key' in self.cleaned_data:
|
||||
try:
|
||||
if EveManager.check_if_api_key_pair_exist(self.cleaned_data['api_id']):
|
||||
logger.debug("UpdateKeyForm failed cleaning as API id %s already exists." % self.cleaned_data['api_id'])
|
||||
raise forms.ValidationError(u'API key already exist')
|
||||
if EveApiManager.api_key_is_valid(self.cleaned_data['api_id'], self.cleaned_data['api_key']) is False:
|
||||
raise forms.ValidationError(u'API key is invalid')
|
||||
if (settings.REJECT_OLD_APIS and
|
||||
EveManager.check_if_api_key_pair_is_new(self.cleaned_data['api_id'], settings.REJECT_OLD_APIS_MARGIN) is False):
|
||||
raise forms.ValidationError(u'API key is too old. Please create a new key')
|
||||
chars = EveApiManager.get_characters_from_api(self.cleaned_data['api_id'], self.cleaned_data['api_key']).result
|
||||
states = []
|
||||
states.append(self.user_state)
|
||||
for char in chars:
|
||||
evechar = EveCharacter()
|
||||
evechar.character_name = chars[char]['name']
|
||||
evechar.corporation_id = chars[char]['corp']['id']
|
||||
evechar.alliance_id = chars[char]['alliance']['id']
|
||||
state = determine_membership_by_character(evechar)
|
||||
logger.debug("API ID %s character %s has state %s" % (self.cleaned_data['api_id'], evechar, state))
|
||||
states.append(state)
|
||||
|
||||
if 'MEMBER' in states:
|
||||
if EveApiManager.validate_member_api(self.cleaned_data['api_id'], self.cleaned_data['api_key']) is False:
|
||||
raise forms.ValidationError(u'API must meet member requirements')
|
||||
if 'BLUE' in states:
|
||||
if EveApiManager.validate_blue_api(self.cleaned_data['api_id'], self.cleaned_data['api_key']) is False:
|
||||
raise forms.ValidationError(u'API must meet blue requirements')
|
||||
return self.cleaned_data
|
||||
except evelink.api.APIError as e:
|
||||
logger.debug("Got error code %s while validating API %s" % (e.code, self.cleaned_data['api_id']))
|
||||
if int(e.code) in [221, 222]:
|
||||
raise forms.ValidationError("API key failed validation")
|
||||
else:
|
||||
raise forms.ValidationError("Failed to reach API servers")
|
||||
if EveManager.check_if_api_key_pair_exist(self.cleaned_data['api_id']):
|
||||
logger.debug("UpdateKeyForm failed cleaning as API id %s already exists." % self.cleaned_data['api_id'])
|
||||
raise forms.ValidationError('API key already exist')
|
||||
if settings.REJECT_OLD_APIS and not EveManager.check_if_api_key_pair_is_new(
|
||||
self.cleaned_data['api_id'],
|
||||
settings.REJECT_OLD_APIS_MARGIN):
|
||||
raise forms.ValidationError('API key is too old. Please create a new key')
|
||||
try:
|
||||
EveApiManager.validate_api(self.cleaned_data['api_id'], self.cleaned_data['api_key'], self.user)
|
||||
return self.cleaned_data
|
||||
except EveApiManager.ApiValidationError as e:
|
||||
raise forms.ValidationError(str(e))
|
||||
except evelink.api.APIError as e:
|
||||
logger.debug("Got error code %s while validating API %s" % (e.code, self.cleaned_data['api_id']))
|
||||
if int(e.code) in [221, 222]:
|
||||
raise forms.ValidationError("API key failed validation")
|
||||
else:
|
||||
raise forms.ValidationError("Failed to reach API servers")
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
from models import EveCharacter
|
||||
from models import EveApiKeyPair
|
||||
from models import EveAllianceInfo
|
||||
from models import EveCorporationInfo
|
||||
from __future__ import unicode_literals
|
||||
from eveonline.models import EveCharacter
|
||||
from eveonline.models import EveApiKeyPair
|
||||
from eveonline.models import EveAllianceInfo
|
||||
from eveonline.models import EveCorporationInfo
|
||||
|
||||
from services.managers.eve_api_manager import EveApiManager
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EveManager:
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -64,8 +66,8 @@ class EveManager:
|
||||
eve_char.save()
|
||||
logger.info("Updated character model %s" % eve_char)
|
||||
else:
|
||||
logger.warn("Attempting to update non-existing character model with name %s" % chars.result[char]['name'])
|
||||
|
||||
logger.warn(
|
||||
"Attempting to update non-existing character model with name %s" % chars.result[char]['name'])
|
||||
|
||||
@staticmethod
|
||||
def create_api_keypair(api_id, api_key, user_id):
|
||||
@@ -163,10 +165,10 @@ class EveManager:
|
||||
return True
|
||||
latest_api_id = int(EveApiKeyPair.objects.order_by('-api_id')[0].api_id) - fudge_factor
|
||||
if latest_api_id >= api_id:
|
||||
logger.debug("api key (%d) is older than latest API key (%d). Rejecting" % (api_id, latest_api_id) )
|
||||
logger.debug("api key (%d) is older than latest API key (%d). Rejecting" % (api_id, latest_api_id))
|
||||
return False
|
||||
else:
|
||||
logger.debug("api key (%d) is new. Accepting" % api_id )
|
||||
logger.debug("api key (%d) is new. Accepting" % api_id)
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
@@ -179,7 +181,9 @@ class EveManager:
|
||||
logger.info("Deleted user %s api key id %s" % (user_id, api_id))
|
||||
apikeypair.delete()
|
||||
else:
|
||||
logger.error("Unable to delete api: user mismatch: key id %s owned by user id %s, not deleting user id %s" % (api_id, apikeypair.user.id, user_id))
|
||||
logger.error(
|
||||
"Unable to delete api: user mismatch: key id %s owned by user id %s, not deleting user id %s" % (
|
||||
api_id, apikeypair.user.id, user_id))
|
||||
else:
|
||||
logger.warn("Unable to locate api id %s - cannot delete." % api_id)
|
||||
|
||||
@@ -195,7 +199,10 @@ class EveManager:
|
||||
logger.info("Deleting user %s character %s from api %s" % (user_id, char, api_id))
|
||||
char.delete()
|
||||
else:
|
||||
logger.error("Unable to delete character %s by api %s: user mismatch: character owned by user id%s, not deleting user id %s" % (char, api_id, char.user.id, user_id))
|
||||
logger.error(
|
||||
"Unable to delete character %s by api %s: user mismatch: character owned by user id %s, "
|
||||
"not deleting user id %s" % (
|
||||
char, api_id, char.user.id, user_id))
|
||||
|
||||
@staticmethod
|
||||
def check_if_character_exist(char_name):
|
||||
|
||||
68
eveonline/migrations/0001_initial.py
Normal file
68
eveonline/migrations/0001_initial.py
Normal file
@@ -0,0 +1,68 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-05 21:39
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='EveAllianceInfo',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('alliance_id', models.CharField(max_length=254)),
|
||||
('alliance_name', models.CharField(max_length=254)),
|
||||
('alliance_ticker', models.CharField(max_length=254)),
|
||||
('executor_corp_id', models.CharField(max_length=254)),
|
||||
('is_blue', models.BooleanField(default=False)),
|
||||
('member_count', models.IntegerField()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EveApiKeyPair',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('api_id', models.CharField(max_length=254)),
|
||||
('api_key', models.CharField(max_length=254)),
|
||||
('error_count', models.PositiveIntegerField(default=0)),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EveCharacter',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('character_id', models.CharField(max_length=254)),
|
||||
('character_name', models.CharField(max_length=254)),
|
||||
('corporation_id', models.CharField(max_length=254)),
|
||||
('corporation_name', models.CharField(max_length=254)),
|
||||
('corporation_ticker', models.CharField(max_length=254)),
|
||||
('alliance_id', models.CharField(max_length=254)),
|
||||
('alliance_name', models.CharField(max_length=254)),
|
||||
('api_id', models.CharField(max_length=254)),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EveCorporationInfo',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('corporation_id', models.CharField(max_length=254)),
|
||||
('corporation_name', models.CharField(max_length=254)),
|
||||
('corporation_ticker', models.CharField(max_length=254)),
|
||||
('member_count', models.IntegerField()),
|
||||
('is_blue', models.BooleanField(default=False)),
|
||||
('alliance', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='eveonline.EveAllianceInfo')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-10 20:20
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('eveonline', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='eveapikeypair',
|
||||
name='error_count',
|
||||
),
|
||||
]
|
||||
0
eveonline/migrations/__init__.py
Normal file
0
eveonline/migrations/__init__.py
Normal file
@@ -1,7 +1,10 @@
|
||||
from __future__ import unicode_literals
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class EveCharacter(models.Model):
|
||||
character_id = models.CharField(max_length=254)
|
||||
character_name = models.CharField(max_length=254)
|
||||
@@ -17,16 +20,17 @@ class EveCharacter(models.Model):
|
||||
return self.character_name
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class EveApiKeyPair(models.Model):
|
||||
api_id = models.CharField(max_length=254)
|
||||
api_key = models.CharField(max_length=254)
|
||||
user = models.ForeignKey(User)
|
||||
error_count = models.PositiveIntegerField(default=0)
|
||||
|
||||
def __str__(self):
|
||||
return self.user.username + " - ApiKeyPair"
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class EveAllianceInfo(models.Model):
|
||||
alliance_id = models.CharField(max_length=254)
|
||||
alliance_name = models.CharField(max_length=254)
|
||||
@@ -39,6 +43,7 @@ class EveAllianceInfo(models.Model):
|
||||
return self.alliance_name
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class EveCorporationInfo(models.Model):
|
||||
corporation_id = models.CharField(max_length=254)
|
||||
corporation_name = models.CharField(max_length=254)
|
||||
|
||||
346
eveonline/tasks.py
Normal file
346
eveonline/tasks.py
Normal file
@@ -0,0 +1,346 @@
|
||||
from __future__ import unicode_literals
|
||||
from django.conf import settings
|
||||
from celery.task import periodic_task
|
||||
from django.contrib.auth.models import User
|
||||
from notifications import notify
|
||||
from celery import task
|
||||
from celery.task.schedules import crontab
|
||||
from authentication.models import AuthServicesInfo
|
||||
from eveonline.managers import EveManager
|
||||
from eveonline.models import EveApiKeyPair
|
||||
from services.managers.eve_api_manager import EveApiManager
|
||||
from eveonline.models import EveCharacter
|
||||
from eveonline.models import EveCorporationInfo
|
||||
from eveonline.models import EveAllianceInfo
|
||||
from authentication.tasks import set_state
|
||||
import logging
|
||||
import evelink
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@task
|
||||
def refresh_api(api):
|
||||
logger.debug('Running update on api key %s' % api.api_id)
|
||||
still_valid = True
|
||||
try:
|
||||
EveApiManager.validate_api(api.api_id, api.api_key, api.user)
|
||||
# Update characters
|
||||
characters = EveApiManager.get_characters_from_api(api.api_id, api.api_key)
|
||||
EveManager.update_characters_from_list(characters)
|
||||
new_character = False
|
||||
for char in characters.result:
|
||||
# Ensure we have a model for all characters on key
|
||||
if not EveManager.check_if_character_exist(characters.result[char]['name']):
|
||||
logger.debug(
|
||||
"API key %s has a new character on the account: %s" % (api.api_id, characters.result[char]['name']))
|
||||
new_character = True
|
||||
if new_character:
|
||||
logger.debug("Creating new character %s from api key %s" % (characters.result[char]['name'], api.api_id))
|
||||
EveManager.create_characters_from_list(characters, api.user, api.api_id)
|
||||
current_chars = EveCharacter.objects.filter(api_id=api.api_id)
|
||||
for c in current_chars:
|
||||
if not int(c.character_id) in characters.result:
|
||||
logger.info("Character %s no longer found on API ID %s" % (c, api.api_id))
|
||||
c.delete()
|
||||
except evelink.api.APIError as e:
|
||||
logger.warning('Received unexpected APIError (%s) while updating API %s' % (e.code, api.api_id))
|
||||
except EveApiManager.ApiInvalidError:
|
||||
logger.debug("API key %s is no longer valid; it and its characters will be deleted." % api.api_id)
|
||||
notify(api.user, "API Failed Validation", message="Your API key ID %s is no longer valid." % api.api_id,
|
||||
level="danger")
|
||||
still_valid = False
|
||||
except EveApiManager.ApiAccountValidationError:
|
||||
logger.info(
|
||||
"Determined api key %s for user %s no longer meets account access requirements." % (api.api_id, api.user))
|
||||
notify(api.user, "API Failed Validation",
|
||||
message="Your API key ID %s is no longer account-wide as required." % api.api_id, level="danger")
|
||||
still_valid = False
|
||||
except EveApiManager.ApiMaskValidationError as e:
|
||||
logger.info("Determined api key %s for user %s no longer meets minimum access mask as required." % (
|
||||
api.api_id, api.user))
|
||||
notify(api.user, "API Failed Validation",
|
||||
message="Your API key ID %s no longer meets access mask requirements. Required: %s Got: %s" % (
|
||||
api.api_id, e.required_mask, e.api_mask), level="danger")
|
||||
still_valid = False
|
||||
finally:
|
||||
if not still_valid:
|
||||
EveManager.delete_characters_by_api_id(api.api_id, api.user.id)
|
||||
EveManager.delete_api_key_pair(api.api_id, api.user.id)
|
||||
notify(api.user, "API Key Deleted",
|
||||
message="Your API key ID %s is invalid. It and its associated characters have been deleted." % api.api_id,
|
||||
level="danger")
|
||||
|
||||
|
||||
@task
|
||||
def refresh_user_apis(user):
|
||||
logger.debug('Refreshing all APIs belonging to user %s' % user)
|
||||
apis = EveApiKeyPair.objects.filter(user=user)
|
||||
for x in apis:
|
||||
refresh_api(x)
|
||||
# Check our main character
|
||||
auth = AuthServicesInfo.objects.get_or_create(user=user)[0]
|
||||
if auth.main_char_id:
|
||||
if EveCharacter.objects.filter(character_id=auth.main_char_id).exists() is False:
|
||||
logger.info(
|
||||
"User %s main character id %s missing model. Clearning main character." % (user, auth.main_char_id))
|
||||
auth.main_char_id = ''
|
||||
auth.save()
|
||||
notify(user, "Main Character Reset",
|
||||
message="Your specified main character no longer has a model.\nThis could be the result of "
|
||||
"an invalid API.\nYour main character ID has been reset.",
|
||||
level="warn")
|
||||
set_state(user)
|
||||
|
||||
|
||||
@periodic_task(run_every=crontab(minute=0, hour="*/3"))
|
||||
def run_api_refresh():
|
||||
for u in User.objects.all():
|
||||
refresh_user_apis.delay(u)
|
||||
|
||||
|
||||
def populate_alliance(id, blue=False):
|
||||
logger.debug("Populating alliance model with id %s blue %s" % (id, blue))
|
||||
alliance_info = EveApiManager.get_alliance_information(id)
|
||||
|
||||
if not alliance_info:
|
||||
raise ValueError("Supplied alliance id %s is invalid" % id)
|
||||
|
||||
if not EveAllianceInfo.objects.filter(alliance_id=id).exists():
|
||||
EveManager.create_alliance_info(alliance_info['id'], alliance_info['name'], alliance_info['ticker'],
|
||||
alliance_info['executor_id'], alliance_info['member_count'], blue)
|
||||
alliance = EveAllianceInfo.objects.get(alliance_id=id)
|
||||
for member_corp in alliance_info['member_corps']:
|
||||
if EveCorporationInfo.objects.filter(corporation_id=member_corp).exists():
|
||||
corp = EveCorporationInfo.objects.get(corporation_id=member_corp)
|
||||
if corp.alliance != alliance:
|
||||
corp.alliance = alliance
|
||||
corp.save()
|
||||
else:
|
||||
logger.info("Creating new alliance member corp id %s" % member_corp)
|
||||
corpinfo = EveApiManager.get_corporation_information(member_corp)
|
||||
EveManager.create_corporation_info(corpinfo['id'], corpinfo['name'], corpinfo['ticker'],
|
||||
corpinfo['members']['current'], blue, alliance)
|
||||
|
||||
|
||||
@task
|
||||
def update_alliance(id):
|
||||
alliance = EveAllianceInfo.objects.get(alliance_id=id)
|
||||
corps = EveCorporationInfo.objects.filter(alliance=alliance)
|
||||
logger.debug("Updating alliance %s with %s member corps" % (alliance, len(corps)))
|
||||
allianceinfo = EveApiManager.get_alliance_information(alliance.alliance_id)
|
||||
if allianceinfo:
|
||||
EveManager.update_alliance_info(allianceinfo['id'], allianceinfo['executor_id'],
|
||||
allianceinfo['member_count'], alliance.is_blue)
|
||||
for corp in corps:
|
||||
if corp.corporation_id in allianceinfo['member_corps'] is False:
|
||||
logger.info("Corp %s no longer in alliance %s" % (corp, alliance))
|
||||
corp.alliance = None
|
||||
corp.save()
|
||||
populate_alliance(alliance.alliance_id, blue=alliance.is_blue)
|
||||
elif EveApiManager.check_if_alliance_exists(alliance.alliance_id) is False:
|
||||
logger.info("Alliance %s has closed. Deleting model" % alliance)
|
||||
alliance.delete()
|
||||
|
||||
|
||||
@task
|
||||
def update_corp(id):
|
||||
corp = EveCorporationInfo.objects.get(corporation_id=id)
|
||||
logger.debug("Updating corp %s" % corp)
|
||||
corpinfo = EveApiManager.get_corporation_information(corp.corporation_id)
|
||||
if corpinfo:
|
||||
alliance = None
|
||||
if EveAllianceInfo.objects.filter(alliance_id=corpinfo['alliance']['id']).exists():
|
||||
alliance = EveAllianceInfo.objects.get(alliance_id=corpinfo['alliance']['id'])
|
||||
EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], alliance, corp.is_blue)
|
||||
elif EveApiManager.check_if_corp_exists(corp.corporation_id) is False:
|
||||
logger.info("Corp %s has closed. Deleting model" % corp)
|
||||
corp.delete()
|
||||
|
||||
# Run Every 2 hours
|
||||
|
||||
|
||||
@periodic_task(run_every=crontab(minute=0, hour="*/2"))
|
||||
def run_corp_update():
|
||||
if EveApiManager.check_if_api_server_online() is False:
|
||||
logger.warn("Aborted updating corp and alliance models: API server unreachable")
|
||||
return
|
||||
standing_level = 'alliance'
|
||||
try:
|
||||
# get corp info for owning corp if required
|
||||
ownercorpinfo = {}
|
||||
if settings.IS_CORP:
|
||||
standing_level = 'corp'
|
||||
logger.debug("Getting information for owning corp with id %s" % settings.CORP_ID)
|
||||
ownercorpinfo = EveApiManager.get_corporation_information(settings.CORP_ID)
|
||||
if not ownercorpinfo:
|
||||
logger.error("Failed to retrieve corp info for owning corp id %s - bad corp id?" % settings.CORP_ID)
|
||||
return
|
||||
|
||||
# check if we need to update an alliance model
|
||||
alliance_id = ''
|
||||
if ownercorpinfo and ownercorpinfo['alliance']['id']:
|
||||
alliance_id = ownercorpinfo['alliance']['id']
|
||||
elif settings.IS_CORP is False:
|
||||
alliance_id = settings.ALLIANCE_ID
|
||||
|
||||
# get and create alliance info for owning alliance if required
|
||||
alliance = None
|
||||
if alliance_id:
|
||||
logger.debug("Getting information for owning alliance with id %s" % alliance_id)
|
||||
ownerallianceinfo = EveApiManager.get_alliance_information(alliance_id)
|
||||
if not ownerallianceinfo:
|
||||
logger.error("Failed to retrieve corp info for owning alliance id %s - bad alliance id?" % alliance_id)
|
||||
return
|
||||
if EveAllianceInfo.objects.filter(alliance_id=ownerallianceinfo['id']).exists():
|
||||
logger.debug("Updating existing owner alliance model with id %s" % alliance_id)
|
||||
EveManager.update_alliance_info(ownerallianceinfo['id'], ownerallianceinfo['executor_id'],
|
||||
ownerallianceinfo['member_count'], False)
|
||||
else:
|
||||
populate_alliance(alliance_id)
|
||||
alliance = EveAllianceInfo.objects.get(alliance_id=alliance_id)
|
||||
|
||||
# create corp info for owning corp if required
|
||||
if ownercorpinfo:
|
||||
if EveCorporationInfo.objects.filter(corporation_id=ownercorpinfo['id']).exists():
|
||||
logger.debug("Updating existing owner corp model with id %s" % ownercorpinfo['id'])
|
||||
EveManager.update_corporation_info(ownercorpinfo['id'], ownercorpinfo['members']['current'], alliance,
|
||||
False)
|
||||
else:
|
||||
logger.info("Creating model for owning corp with id %s" % ownercorpinfo['id'])
|
||||
EveManager.create_corporation_info(ownercorpinfo['id'], ownercorpinfo['name'], ownercorpinfo['ticker'],
|
||||
ownercorpinfo['members']['current'], False, alliance)
|
||||
|
||||
# validate and create corp models for member corps of owning alliance
|
||||
if alliance:
|
||||
current_corps = EveCorporationInfo.objects.filter(alliance=alliance)
|
||||
for corp in current_corps:
|
||||
if corp.corporation_id in ownerallianceinfo['member_corps'] is False:
|
||||
logger.info("Corp %s is no longer in owning alliance %s - updating model." % (corp, alliance))
|
||||
corp.alliance = None
|
||||
corp.save()
|
||||
for member_corp in ownerallianceinfo['member_corps']:
|
||||
if EveCorporationInfo.objects.filter(corporation_id=member_corp).exists():
|
||||
corp = EveCorporationInfo.objects.get(corporation_id=member_corp)
|
||||
if corp.alliance == alliance is not True:
|
||||
logger.info("Associating corp %s with owning alliance %s" % (corp, alliance))
|
||||
corp.alliance = alliance
|
||||
corp.save()
|
||||
else:
|
||||
corpinfo = EveApiManager.get_corporation_information(member_corp)
|
||||
logger.info("Creating model for owning alliance member corp with id %s" % corpinfo['id'])
|
||||
EveManager.create_corporation_info(corpinfo['id'], corpinfo['name'], corpinfo['ticker'],
|
||||
corpinfo['members']['current'], False, alliance)
|
||||
|
||||
# update existing corp models
|
||||
for corp in EveCorporationInfo.objects.all():
|
||||
update_corp.delay(corp.corporation_id)
|
||||
|
||||
# update existing alliance models
|
||||
for alliance in EveAllianceInfo.objects.all():
|
||||
update_alliance.delay(alliance.alliance_id)
|
||||
|
||||
# create standings
|
||||
standings = EveApiManager.get_corp_standings()
|
||||
if standings:
|
||||
standings = standings[standing_level]
|
||||
for standing in standings:
|
||||
if int(standings[standing]['standing']) >= settings.BLUE_STANDING:
|
||||
logger.debug("Standing %s meets threshold" % standing)
|
||||
if EveApiManager.check_if_id_is_alliance(standing):
|
||||
logger.debug("Standing %s is an alliance" % standing)
|
||||
if EveAllianceInfo.objects.filter(alliance_id=standing).exists():
|
||||
alliance = EveAllianceInfo.objects.get(alliance_id=standing)
|
||||
if alliance.is_blue is not True:
|
||||
logger.info("Updating alliance %s as blue" % alliance)
|
||||
alliance.is_blue = True
|
||||
alliance.save()
|
||||
else:
|
||||
populate_alliance(standing, blue=True)
|
||||
elif EveApiManager.check_if_id_is_corp(standing):
|
||||
logger.debug("Standing %s is a corp" % standing)
|
||||
if EveCorporationInfo.objects.filter(corporation_id=standing).exists():
|
||||
corp = EveCorporationInfo.objects.get(corporation_id=standing)
|
||||
if corp.is_blue is not True:
|
||||
logger.info("Updating corp %s as blue" % corp)
|
||||
corp.is_blue = True
|
||||
corp.save()
|
||||
else:
|
||||
logger.info("Creating model for blue corp with id %s" % standing)
|
||||
corpinfo = EveApiManager.get_corporation_information(standing)
|
||||
corp_alliance = None
|
||||
if EveAllianceInfo.objects.filter(alliance_id=corpinfo['alliance']['id']).exists():
|
||||
logger.debug("New corp model for standing %s has existing alliance model" % standing)
|
||||
corp_alliance = EveAllianceInfo.objects.get(alliance_id=corpinfo['alliance']['id'])
|
||||
EveManager.create_corporation_info(corpinfo['id'], corpinfo['name'], corpinfo['ticker'],
|
||||
corpinfo['members']['current'], True, corp_alliance)
|
||||
|
||||
# update alliance standings
|
||||
for alliance in EveAllianceInfo.objects.filter(is_blue=True):
|
||||
if int(alliance.alliance_id) in standings:
|
||||
if float(standings[int(alliance.alliance_id)]['standing']) < float(settings.BLUE_STANDING):
|
||||
logger.info("Alliance %s no longer meets minimum blue standing threshold" % alliance)
|
||||
alliance.is_blue = False
|
||||
alliance.save()
|
||||
else:
|
||||
logger.info("Alliance %s no longer in standings" % alliance)
|
||||
alliance.is_blue = False
|
||||
alliance.save()
|
||||
|
||||
# update corp standings
|
||||
for corp in EveCorporationInfo.objects.filter(is_blue=True):
|
||||
if int(corp.corporation_id) in standings:
|
||||
if float(standings[int(corp.corporation_id)]['standing']) < float(settings.BLUE_STANDING):
|
||||
logger.info("Corp %s no longer meets minimum blue standing threshold" % corp)
|
||||
corp.is_blue = False
|
||||
corp.save()
|
||||
else:
|
||||
if corp.alliance:
|
||||
if not corp.alliance.is_blue:
|
||||
logger.info("Corp %s and its alliance %s are no longer blue" % (corp, corp.alliance))
|
||||
corp.is_blue = False
|
||||
corp.save()
|
||||
else:
|
||||
logger.info("Corp %s is no longer blue" % corp)
|
||||
corp.is_blue = False
|
||||
corp.save()
|
||||
|
||||
# delete unnecessary alliance models
|
||||
for alliance in EveAllianceInfo.objects.filter(is_blue=False):
|
||||
logger.debug("Checking to delete alliance %s" % alliance)
|
||||
if not settings.IS_CORP:
|
||||
if not alliance.alliance_id == settings.ALLIANCE_ID:
|
||||
logger.info("Deleting unnecessary alliance model %s" % alliance)
|
||||
alliance.delete()
|
||||
else:
|
||||
if not alliance.evecorporationinfo_set.filter(corporation_id=settings.CORP_ID).exists():
|
||||
logger.info("Deleting unnecessary alliance model %s" % alliance)
|
||||
alliance.delete()
|
||||
|
||||
# delete unnecessary corp models
|
||||
for corp in EveCorporationInfo.objects.filter(is_blue=False):
|
||||
logger.debug("Checking to delete corp %s" % corp)
|
||||
if not settings.IS_CORP:
|
||||
if corp.alliance:
|
||||
logger.debug("Corp %s has alliance %s" % (corp, corp.alliance))
|
||||
if not corp.alliance.alliance_id == settings.ALLIANCE_ID:
|
||||
logger.info("Deleting unnecessary corp model %s" % corp)
|
||||
corp.delete()
|
||||
else:
|
||||
logger.info("Deleting unnecessary corp model %s" % corp)
|
||||
corp.delete()
|
||||
else:
|
||||
if corp.corporation_id != settings.CORP_ID:
|
||||
logger.debug("Corp %s is not owning corp" % corp)
|
||||
if corp.alliance:
|
||||
logger.debug("Corp %s has alliance %s" % (corp, corp.alliance))
|
||||
if not corp.alliance.evecorporationinfo_set.filter(corporation_id=settings.CORP_ID).exists():
|
||||
logger.info("Deleting unnecessary corp model %s" % corp)
|
||||
corp.delete()
|
||||
else:
|
||||
logger.info("Deleting unnecessary corp model %s" % corp)
|
||||
corp.delete()
|
||||
else:
|
||||
logger.debug("Corp %s is owning corp" % corp)
|
||||
except evelink.api.APIError as e:
|
||||
logger.error("Model update failed with error code %s" % e.code)
|
||||
@@ -1,59 +1,27 @@
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
from __future__ import unicode_literals
|
||||
from django.shortcuts import render, redirect
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.decorators import permission_required
|
||||
from django.contrib import messages
|
||||
|
||||
from util import add_member_permission
|
||||
from util import remove_member_permission
|
||||
from util import check_if_user_has_permission
|
||||
from forms import UpdateKeyForm
|
||||
from managers import EveManager
|
||||
from eveonline.forms import UpdateKeyForm
|
||||
from eveonline.managers import EveManager
|
||||
from authentication.managers import AuthServicesInfoManager
|
||||
from services.managers.eve_api_manager import EveApiManager
|
||||
from util.common_task import add_user_to_group
|
||||
from util.common_task import remove_user_from_group
|
||||
from util.common_task import deactivate_services
|
||||
from util.common_task import generate_corp_group_name
|
||||
from eveonline.models import EveCorporationInfo
|
||||
from eveonline.models import EveCharacter
|
||||
from eveonline.models import EveApiKeyPair
|
||||
from authentication.models import AuthServicesInfo
|
||||
from celerytask.tasks import determine_membership_by_user
|
||||
from celerytask.tasks import set_state
|
||||
from celerytask.tasks import refresh_api
|
||||
from authentication.tasks import set_state
|
||||
from eveonline.tasks import refresh_api
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def disable_member(user, char_id):
|
||||
logger.debug("Disabling user %s with character id %s" % (user, char_id))
|
||||
remove_member_permission(user, 'member')
|
||||
remove_user_from_group(user, settings.DEFAULT_AUTH_GROUP)
|
||||
remove_user_from_group(user,
|
||||
generate_corp_group_name(
|
||||
EveManager.get_character_by_id(char_id).corporation_name))
|
||||
deactivate_services(user)
|
||||
logger.info("Disabled member %s" % user)
|
||||
|
||||
|
||||
def disable_blue_member(user):
|
||||
logger.debug("Disabling blue user %s" % user)
|
||||
remove_member_permission(user, 'blue_member')
|
||||
remove_user_from_group(user, settings.DEFAULT_BLUE_GROUP)
|
||||
deactivate_services(user)
|
||||
logger.info("Disabled blue user %s" % user)
|
||||
|
||||
@login_required
|
||||
def add_api_key(request):
|
||||
logger.debug("add_api_key called by user %s" % request.user)
|
||||
user_state = determine_membership_by_user(request.user)
|
||||
if request.method == 'POST':
|
||||
form = UpdateKeyForm(request.POST)
|
||||
form.user_state=user_state
|
||||
form = UpdateKeyForm(request.user, request.POST)
|
||||
logger.debug("Request type POST with form valid: %s" % form.is_valid())
|
||||
if form.is_valid():
|
||||
EveManager.create_api_keypair(form.cleaned_data['api_id'],
|
||||
@@ -65,16 +33,18 @@ def add_api_key(request):
|
||||
form.cleaned_data['api_key'])
|
||||
EveManager.create_characters_from_list(characters, request.user, form.cleaned_data['api_id'])
|
||||
logger.info("Successfully processed api add form for user %s" % request.user)
|
||||
return HttpResponseRedirect("/api_key_management/")
|
||||
messages.success(request, 'Added API key %s to your account.' % form.cleaned_data['api_id'])
|
||||
auth = AuthServicesInfo.objects.get_or_create(user=request.user)[0]
|
||||
if not auth.main_char_id:
|
||||
messages.warning(request, 'Please select a main character.')
|
||||
return redirect("/api_key_management/")
|
||||
else:
|
||||
logger.debug("Form invalid: returning to form.")
|
||||
else:
|
||||
logger.debug("Providing empty update key form for user %s" % request.user)
|
||||
form = UpdateKeyForm()
|
||||
form.user_state = user_state
|
||||
form = UpdateKeyForm(request.user)
|
||||
context = {'form': form, 'apikeypairs': EveManager.get_api_key_pairs(request.user.id)}
|
||||
return render_to_response('registered/addapikey.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
return render(request, 'registered/addapikey.html', context=context)
|
||||
|
||||
|
||||
@login_required
|
||||
@@ -82,51 +52,48 @@ def api_key_management_view(request):
|
||||
logger.debug("api_key_management_view called by user %s" % request.user)
|
||||
context = {'apikeypairs': EveManager.get_api_key_pairs(request.user.id)}
|
||||
|
||||
return render_to_response('registered/apikeymanagment.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
return render(request, 'registered/apikeymanagment.html', context=context)
|
||||
|
||||
|
||||
@login_required
|
||||
def api_key_removal(request, api_id):
|
||||
logger.debug("api_key_removal called by user %s for api id %s" % (request.user, api_id))
|
||||
authinfo = AuthServicesInfoManager.get_auth_service_info(request.user)
|
||||
authinfo = AuthServicesInfo.objects.get_or_create(user=request.user)[0]
|
||||
# Check if our users main id is in the to be deleted characters
|
||||
characters = EveManager.get_characters_by_owner_id(request.user.id)
|
||||
if characters is not None:
|
||||
for character in characters:
|
||||
if character.character_id == authinfo.main_char_id:
|
||||
if character.api_id == api_id:
|
||||
# TODO: Remove services also
|
||||
if authinfo.is_blue:
|
||||
logger.debug("Blue user %s deleting api for main character. Disabling." % request.user)
|
||||
disable_blue_member(request.user)
|
||||
else:
|
||||
logger.debug("User %s deleting api for main character. Disabling." % request.user)
|
||||
disable_member(request.user, authinfo.main_char_id)
|
||||
messages.warning(request,
|
||||
'You have deleted your main character. Please select a new main character.')
|
||||
set_state(request.user)
|
||||
|
||||
EveManager.delete_api_key_pair(api_id, request.user.id)
|
||||
EveManager.delete_characters_by_api_id(api_id, request.user.id)
|
||||
messages.success(request, 'Deleted API key %s' % api_id)
|
||||
logger.info("Succesfully processed api delete request by user %s for api %s" % (request.user, api_id))
|
||||
return HttpResponseRedirect("/api_key_management/")
|
||||
return redirect("auth_api_key_management")
|
||||
|
||||
|
||||
@login_required
|
||||
def characters_view(request):
|
||||
logger.debug("characters_view called by user %s" % request.user)
|
||||
render_items = {'characters': EveManager.get_characters_by_owner_id(request.user.id),
|
||||
'authinfo': AuthServicesInfoManager.get_auth_service_info(request.user)}
|
||||
return render_to_response('registered/characters.html', render_items, context_instance=RequestContext(request))
|
||||
'authinfo': AuthServicesInfo.objects.get_or_create(user=request.user)[0]}
|
||||
return render(request, 'registered/characters.html', context=render_items)
|
||||
|
||||
|
||||
@login_required
|
||||
def main_character_change(request, char_id):
|
||||
logger.debug("main_character_change called by user %s for character id %s" % (request.user, char_id))
|
||||
if EveManager.check_if_character_owned_by_user(char_id, request.user):
|
||||
AuthServicesInfoManager.update_main_char_Id(char_id, request.user)
|
||||
AuthServicesInfoManager.update_main_char_id(char_id, request.user)
|
||||
set_state(request.user)
|
||||
return HttpResponseRedirect("/characters/")
|
||||
return HttpResponseRedirect("/characters/")
|
||||
|
||||
messages.success(request, 'Changed main character ID to %s' % char_id)
|
||||
return redirect("auth_characters")
|
||||
messages.error(request, 'Failed to change main character - selected character is not owned by your account.')
|
||||
return redirect("auth_characters")
|
||||
|
||||
|
||||
@login_required
|
||||
@@ -136,9 +103,12 @@ def user_refresh_api(request, api_id):
|
||||
api_key_pair = EveApiKeyPair.objects.get(api_id=api_id)
|
||||
if api_key_pair.user == request.user:
|
||||
refresh_api(api_key_pair)
|
||||
messages.success(request, 'Refreshed API key %s' % api_id)
|
||||
set_state(request.user)
|
||||
else:
|
||||
messages.warning(request, 'You are not authorized to refresh that API key.')
|
||||
logger.warn("User %s not authorized to refresh api id %s" % (request.user, api_id))
|
||||
else:
|
||||
messages.warning(request, 'Unable to locate API key %s' % api_id)
|
||||
logger.warn("User %s unable to refresh api id %s - api key not found" % (request.user, api_id))
|
||||
return HttpResponseRedirect("/api_key_management/")
|
||||
return redirect("auth_api_key_management")
|
||||
|
||||
Reference in New Issue
Block a user