Merge pull request #9 from R4stl1n/master

sync
This commit is contained in:
Mr McClain 2016-02-15 17:46:52 -06:00
commit 863744095c
16 changed files with 452 additions and 232 deletions

View File

@ -16,7 +16,7 @@ Join us in-game in the channel allianceauth for help and feature requests.
Special Thanks: Special Thanks:
Thanking [Nikdoof](https://github.com/nikdoof), without his old auth Thanking Nikdoof, without his old auth
implementation this project wouldn't be as far as it is now. implementation this project wouldn't be as far as it is now.
Thanks to Raynaldo for his original work on this system and getting it as far as it is today. Thanks to Raynaldo for his original work on this system and getting it as far as it is today.
@ -74,6 +74,7 @@ Special Permissions In Admin:
auth | user | sigtracker_view ( Allows for an individual view signitures) auth | user | sigtracker_view ( Allows for an individual view signitures)
auth | user | optimer_management ( Allows for an individual to create and remove fleet operations) auth | user | optimer_management ( Allows for an individual to create and remove fleet operations)
auth | user | optimer_view ( Allows for an individual view fleet operations) auth | user | optimer_view ( Allows for an individual view fleet operations)
auth | user | logging_notifications ( Generate notifications from logging)
Active Developers Active Developers

View File

@ -61,6 +61,7 @@ INSTALLED_APPS = (
'sigtracker', 'sigtracker',
'optimer', 'optimer',
'corputils', 'corputils',
'notifications',
) )
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
@ -126,6 +127,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'util.context_processors.domain_url', 'util.context_processors.domain_url',
'util.context_processors.member_api_mask', 'util.context_processors.member_api_mask',
'util.context_processors.blue_api_mask', 'util.context_processors.blue_api_mask',
'notifications.context_processors.user_notification_count',
) )
TEMPLATE_DIRS = ( TEMPLATE_DIRS = (
@ -408,67 +410,72 @@ LOGGING = {
'level': 'DEBUG', # edit this line to change logging level to console 'level': 'DEBUG', # edit this line to change logging level to console
'class': 'logging.StreamHandler', 'class': 'logging.StreamHandler',
'formatter': 'verbose', 'formatter': 'verbose',
} },
'notifications': { # creates notifications for users with logging_notifications permission
'level': 'ERROR', # edit this line to change logging level to notifications
'class': 'notifications.handlers.NotificationHandler',
'formatter': 'verbose',
},
}, },
'loggers': { 'loggers': {
'authentication': { 'authentication': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'celerytask': { 'celerytask': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'eveonline': { 'eveonline': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'groupmanagement': { 'groupmanagement': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'hrapplications': { 'hrapplications': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'portal': { 'portal': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'registration': { 'registration': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'services': { 'services': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'srp': { 'srp': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'timerboard': { 'timerboard': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'sigtracker': { 'sigtracker': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'optimer': { 'optimer': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'corputils': { 'corputils': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'util': { 'util': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'DEBUG', 'level': 'DEBUG',
}, },
'django': { 'django': {
'handlers': ['log_file', 'console'], 'handlers': ['log_file', 'console', 'notifications'],
'level': 'ERROR', 'level': 'ERROR',
}, },
} }

View File

@ -186,4 +186,7 @@ urlpatterns = patterns('',
url(r'^remove_optimer/(\w+)', 'optimer.views.remove_optimer', name='auth_remove_optimer'), url(r'^remove_optimer/(\w+)', 'optimer.views.remove_optimer', name='auth_remove_optimer'),
url(r'^edit_optimer/(\w+)$', 'optimer.views.edit_optimer', name='auth_edit_optimer'), url(r'^edit_optimer/(\w+)$', 'optimer.views.edit_optimer', name='auth_edit_optimer'),
# Notifications
url(r'^notifications/$', 'notifications.views.notification_list', name='auth_notification_list'),
url(r'^notifications/(\w+)/$', 'notifications.views.notification_view', name='auth_notification_view'),
) )

View File

@ -25,6 +25,7 @@ from util.common_task import remove_user_from_group
from util.common_task import generate_corp_group_name from util.common_task import generate_corp_group_name
from eveonline.models import EveCharacter from eveonline.models import EveCharacter
from eveonline.models import EveCorporationInfo from eveonline.models import EveCorporationInfo
from eveonline.models import EveAllianceInfo
from authentication.managers import AuthServicesInfoManager from authentication.managers import AuthServicesInfoManager
from services.models import DiscordAuthToken from services.models import DiscordAuthToken
@ -496,222 +497,232 @@ def run_api_refresh():
authserviceinfo.save() authserviceinfo.save()
set_state(user) set_state(user)
def populate_alliance(id, blue=False):
logger.info("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 EveAllianceInfo.objects.filter(alliance_id=id).exists():
alliance = EveAllianceInfo.objects.get(alliance_id=id)
else:
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)
# Run Every 2 hours # Run Every 2 hours
@periodic_task(run_every=crontab(minute=0, hour="*/2")) @periodic_task(run_every=crontab(minute=0, hour="*/2"))
def run_corp_update(): def run_corp_update():
# I am not proud of this block of code if EveApiManager.check_if_api_server_online() is False:
if EveApiManager.check_if_api_server_online(): logger.warn("Aborted updating corp and alliance models: API server unreachable")
logger.debug("API server online and reachable. Proceeding with corp update.") return
if settings.IS_CORP: standing_level = 'alliance'
# Create the corp
logger.debug("Ensuring corp model exists for owning corp id %s due to settings.IS_CORP %s" % (settings.CORP_ID, settings.IS_CORP)) # get corp info for owning corp if required
ownercorpinfo = EveApiManager.get_corporation_information(settings.CORP_ID) ownercorpinfo = {}
logger.debug("Determined ownercorp info: %s" % ownercorpinfo) if settings.IS_CORP:
if not EveManager.check_if_corporation_exists_by_id(ownercorpinfo['id']): standing_level = 'corp'
logger.debug("Owning corp id %s does not have a model. Creating." % ownercorpinfo['id']) logger.debug("Getting information for owning corp with id %s" % settings.CORP_ID)
if ownercorpinfo['alliance']['id'] is None: ownercorpinfo = EveApiManager.get_corporation_information(settings.CORP_ID)
logger.debug("Owning corp does not have an alliance. Creating model with alliance=None") if not ownercorpinfo:
EveManager.create_corporation_info(ownercorpinfo['id'], ownercorpinfo['name'], ownercorpinfo['ticker'], logger.error("Failed to retrieve corp info for owning corp id %s - bad corp id?" % settings.CORP_ID)
ownercorpinfo['members']['current'], False, None) return
else:
alliance_info = EveApiManager.get_alliance_information(ownercorpinfo['alliance']['id']) # check if we need to update an alliance model
logger.debug("Owning corp has an alliance, got info: %s" % alliance_info) alliance_id = ''
if not EveManager.check_if_alliance_exists_by_id(ownercorpinfo['alliance']['id']): if ownercorpinfo and ownercorpinfo['alliance']['id']:
logger.debug("Owning corp missing alliance model. Creating for id %s" % ownercorpinfo['alliance']['id']) alliance_id = ownercorpinfo['alliance']['id']
EveManager.create_alliance_info(ownercorpinfo['alliance']['id'], alliance_info['name'], alliance_info['ticker'], elif settings.IS_CORP is False:
alliance_info['executor_id'], alliance_info['member_count'], False) alliance_id = settings.ALLIANCE_ID
alliance = EveManager.get_alliance_info_by_id(ownercorpinfo['alliance']['id'])
logger.debug("Got alliance model %s for owning corp. Creating corp model." % alliance) # get and create alliance info for owning alliance if required
EveManager.create_corporation_info(ownercorpinfo['id'], ownercorpinfo['name'], ownercorpinfo['ticker'], 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) ownercorpinfo['members']['current'], False, alliance)
else: # validate and create corp models for member corps of owning alliance
# Updated alliance info if alliance:
logger.debug("Getting info for owning alliance %s" % settings.ALLIANCE_ID) current_corps = EveCorporationInfo.objects.filter(alliance=alliance)
alliance_info = EveApiManager.get_alliance_information(settings.ALLIANCE_ID) for corp in current_corps:
logger.debug("Owning alliance info: %s" % alliance_info) if corp.corporation_id in ownerallianceinfo['member_corps'] is False:
# Populate alliance info logger.info("Corp %s is no longer in owning alliance %s - updating model." % (corp, alliance))
if not EveManager.check_if_alliance_exists_by_id(settings.ALLIANCE_ID): corp.alliance = None
logger.debug("Missing alliance model for owning alliance. Creating with id %s" % settings.ALLIANCE_ID) corp.save()
EveManager.create_alliance_info(settings.ALLIANCE_ID, alliance_info['name'], alliance_info['ticker'], for member_corp in ownerallianceinfo['member_corps']:
alliance_info['executor_id'], alliance_info['member_count'], False) if EveCorporationInfo.objects.filter(corporation_id=member_corp).exists():
alliance = EveManager.get_alliance_info_by_id(settings.ALLIANCE_ID) corp = EveCorporationInfo.objects.get(corporation_id=member_corp)
logger.debug("Got owning alliance model %s" % alliance) if corp.alliance == alliance is not True:
# Create the corps in the alliance logger.info("Associating corp %s with owning alliance %s" % (corp, alliance))
for alliance_corp in alliance_info['member_corps']: corp.alliance = alliance
corpinfo = EveApiManager.get_corporation_information(alliance_corp) corp.save()
logger.debug("Got corpinfo for alliance member corp: %s" % corpinfo)
if not EveManager.check_if_corporation_exists_by_id(corpinfo['id']):
logger.debug("Alliance member corp id %s missing model - creating." % corpinfo['id'])
EveManager.create_corporation_info(corpinfo['id'], corpinfo['name'], corpinfo['ticker'],
corpinfo['members']['current'], False, alliance)
#determine what level of standings to check
#refer to https://github.com/eve-val/evelink/blob/master/evelink/parsing/contact_list.py#L43
standing_level = 'alliance'
if settings.IS_CORP:
logger.debug("Switching standings check to corp level.")
standing_level = 'corp'
# Create the corps in the standings
corp_standings = EveApiManager.get_corp_standings()
logger.debug("Got %s corp standings." % len(corp_standings))
if corp_standings:
for standing_id in EveApiManager.get_corp_standings()[standing_level]:
logger.debug("Processing standing id %s" % standing_id)
if int(corp_standings[standing_level][standing_id]['standing']) >= settings.BLUE_STANDING:
logger.debug("Standing %s meets or exceeds blue threshold." % standing_id)
if EveApiManager.check_if_id_is_character(standing_id):
logger.debug("Standing id %s is a character. Not creating model.")
pass
elif EveApiManager.check_if_id_is_corp(standing_id):
corpinfo = EveApiManager.get_corporation_information(standing_id)
logger.debug("Standing id %s is a corp. Got corpinfo: %s" % (standing_id, corpinfo))
if not EveManager.check_if_corporation_exists_by_id(standing_id):
logger.debug("Corp model for standing id %s does not exist. Creating" % standing_id)
EveManager.create_corporation_info(corpinfo['id'], corpinfo['name'], corpinfo['ticker'],
corpinfo['members']['current'], True, None)
else:
# Alliance id create corps
blue_alliance_info = EveApiManager.get_alliance_information(standing_id)
logger.debug("Standing id %s is alliance. Got alliance info: %s" % (standing_id, blue_alliance_info))
if not EveManager.check_if_alliance_exists_by_id(standing_id):
logger.debug("Alliance model for standing id %s does not exist. Creating" % standing_id)
EveManager.create_alliance_info(standing_id, blue_alliance_info['name'],
blue_alliance_info['ticker'],
blue_alliance_info['executor_id'],
blue_alliance_info['member_count'], True)
blue_alliance = EveManager.get_alliance_info_by_id(standing_id)
logger.debug("Got alliance model %s for standing id %s" % (blue_alliance, standing_id))
for blue_alliance_corp in blue_alliance_info['member_corps']:
blue_info = EveApiManager.get_corporation_information(blue_alliance_corp)
logger.debug("Got corpinfo for member corp id %s of blue alliance %s: %s" % (blue_info['id'], blue_alliance, blue_info))
if not EveManager.check_if_corporation_exists_by_id(blue_info['id']):
logger.debug("Blue alliance %s member corp id %s missing model. Creating." % (blue_alliance, blue_info['id']))
EveManager.create_corporation_info(blue_info['id'], blue_info['name'],
blue_info['ticker'],
blue_info['members']['current'], True, blue_alliance)
# Update all allinace info's
for all_alliance_info in EveManager.get_all_alliance_info():
logger.debug("Validating alliance model %s" % all_alliance_info)
if EveApiManager.check_if_alliance_exists(all_alliance_info.alliance_id):
all_alliance_api_info = EveApiManager.get_alliance_information(all_alliance_info.alliance_id)
logger.debug("Got alliance %s alliance info: %s" % (all_alliance_info, all_alliance_api_info))
if (not settings.IS_CORP and all_alliance_info.alliance_id == settings.ALLIANCE_ID):
logger.debug("Alliance %s is owning alliance. Updating info." % all_alliance_info)
EveManager.update_alliance_info(all_alliance_api_info['id'], all_alliance_api_info['executor_id'],
all_alliance_api_info['member_count'], False)
elif standing_level in corp_standings:
if int(all_alliance_info.alliance_id) in corp_standings[standing_level]:
if int(corp_standings[standing_level][int(all_alliance_info.alliance_id)][
'standing']) >= settings.BLUE_STANDING:
logger.debug("Alliance %s is blue. Updating." % all_alliance_info)
EveManager.update_alliance_info(all_alliance_api_info['id'],
all_alliance_api_info['executor_id'],
all_alliance_api_info['member_count'], True)
else:
logger.debug("Alliance %s does not meet blue standing threshold. Updating as non-blue." % all_alliance_info)
EveManager.update_alliance_info(all_alliance_api_info['id'],
all_alliance_api_info['executor_id'],
all_alliance_api_info['member_count'], False)
else:
logger.debug("Alliance %s not in standings. Updating as non-blue." % all_alliance_info)
EveManager.update_alliance_info(all_alliance_api_info['id'],
all_alliance_api_info['executor_id'],
all_alliance_api_info['member_count'], False)
else:
logger.debug("No standings found. Updating alliance %s as non-blue." % all_alliance_info)
EveManager.update_alliance_info(all_alliance_api_info['id'],
all_alliance_api_info['executor_id'],
all_alliance_api_info['member_count'], False)
else:
logger.info("Alliance %s has closed. Deleting model." % all_alliance_info)
#alliance no longer exists
all_alliance_info.delete()
# Update corp infos
for all_corp_info in EveManager.get_all_corporation_info():
logger.debug("Validating corp model %s" % all_corp_info)
if EveApiManager.check_if_corp_exists(all_corp_info.corporation_id):
alliance = None
corpinfo = EveApiManager.get_corporation_information(all_corp_info.corporation_id)
if corpinfo['alliance']['id'] is not None:
alliance = EveManager.get_alliance_info_by_id(corpinfo['alliance']['id'])
logger.debug("Got corpinfo %s and allianceinfo %s" % (corpinfo, alliance))
if (settings.IS_CORP and all_corp_info.corporation_id == settings.CORP_ID):
logger.debug("Corp %s is owning corp. Updating." % all_corp_info)
EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], None, False)
elif int(all_corp_info.corporation_id) in corp_standings[standing_level]:
if int(corp_standings[standing_level][int(all_corp_info.corporation_id)][
'standing']) >= settings.BLUE_STANDING:
logger.debug("Corp %s is blue. Updating." % all_corp_info)
EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], None, True)
else:
logger.debug("Corp %s does not meet blue standing threshold. Updating as non-blue." % all_corp_info)
EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], None, False)
elif alliance is not None and all_corp_info.alliance is not None:
logger.debug("Corp %s not in standings - checking alliance with model %s" % (all_corp_info, alliance))
if (not settings.IS_CORP) and (all_corp_info.alliance.alliance_id == settings.ALLIANCE_ID):
logger.debug("Corp %s is member of owning alliance. Updating." % all_corp_info)
EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], alliance, False)
elif int(alliance.alliance_id) in corp_standings[standing_level]:
if int(corp_standings[standing_level][int(alliance.alliance_id)][
'standing']) >= settings.BLUE_STANDING:
logger.debug("Corp %s alliance %s is blue. Updating." % (all_corp_info, alliance))
EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], alliance,
True)
else:
logger.debug("Corp %s alliance %s does not meet blue standing threshold. Updating as non-blue." % (all_corp_info, alliance))
EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], alliance,
False)
else:
logger.debug("Corp %s alliance %s not found in standings. Updating as non-blue." % (all_corp_info, alliance))
EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], alliance,
False)
else:
logger.info("Corp model %s is not owning, member of owning alliance, or in standings. Updating as non-blue." % all_corp_info)
EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], None, False)
else:
#corp has closed
logger.info("Corp %s has closed. Deleting model." % all_corp_info)
all_corp_info.delete()
# Remove irrelevent corp and alliance models
# Check the corps
for all_corp_info in EveManager.get_all_corporation_info():
logger.debug("Checking to delete corp model %s" % all_corp_info)
if settings.IS_CORP:
if all_corp_info.corporation_id != settings.CORP_ID:
if not all_corp_info.is_blue:
logger.info("Corp model %s is not owning corp nor blue. Deleting." % all_corp_info)
all_corp_info.delete()
else: else:
if all_corp_info.alliance is not None: corpinfo = EveApiManager.get_corporation_information(member_corp)
if all_corp_info.alliance.alliance_id != settings.ALLIANCE_ID: logger.info("Creating model for owning alliance member corp with id %s" % corpinfo['id'])
if not all_corp_info.is_blue: EveManager.create_corporation_info(corpinfo['id'], corpinfo['name'], corpinfo['ticker'],
logger.info("Corp model %s not in owning alliance nor blue. Deleting." % all_corp_info) corpinfo['members']['current'], False, alliance)
all_corp_info.delete()
elif not all_corp_info.is_blue:
logger.info("Corp model %s has no alliance and is not blue. Deleting." % all_corp_info)
all_corp_info.delete()
# Check the alliances # update existing corp models
for all_alliance_info in EveManager.get_all_alliance_info(): for corp in EveCorporationInfo.objects.all():
logger.debug("Checking to delete alliance model %s" % all_alliance_info) logger.debug("Updating corp %s" % corp)
if settings.IS_CORP: corpinfo = EveApiManager.get_corporation_information(corp.corporation_id)
if all_alliance_info.is_blue is not True: if corpinfo:
if ownercorpinfo['alliance']['id'] is not None: alliance = None
if int(all_alliance_info.alliance_id) != ownercorpinfo['alliance']['id']: if EveAllianceInfo.objects.filter(alliance_id=corpinfo['alliance']['id']).exists():
logger.info("Alliance model %s not owning corp alliance nor blue. Deleting." % all_alliance_info) alliance = EveAllianceInfo.objects.get(alliance_id=corpinfo['alliance']['id'])
all_alliance_info.delete() 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()
# update existing alliance models
for alliance in EveAllianceInfo.objects.all():
logger.debug("Updating alliance %s" % alliance)
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 EveCorporationInfo.objects.filter(alliance=alliance):
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()
# 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: else:
logger.info("Alliance model %s not blue to alliance-less owning corp. Deleting." % all_alliance_info) populate_alliance(standing, blue=True)
all_alliance_info.delete() elif EveApiManager.check_if_id_is_corp(standing):
elif all_alliance_info.alliance_id != settings.ALLIANCE_ID: logger.debug("Standing %s is a corp" % standing)
if all_alliance_info.is_blue is not True: if EveCorporationInfo.objects.filter(corporation_id=standing).exists():
logger.info("Alliance model %s not owning alliance nor blue. Deleting." % all_alliance_info) corp = EveCorporationInfo.objects.get(corporation_id=standing)
all_alliance_info.delete() 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 corp.alliance.is_blue is False:
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 settings.IS_CORP is False:
if alliance.alliance_id == settings.ALLIANCE_ID is False:
logger.info("Deleting unnecessary alliance model %s" % alliance)
alliance.delete()
else:
if alliance.evecorporationinfo_set.filter(corporation_id=settings.CORP_ID).exists() is False:
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 settings.IS_CORP is False:
if corp.alliance:
logger.debug("Corp %s has alliance %s" % (corp, corp.alliance))
if corp.alliance.alliance_id == settings.ALLIANCE_ID is False:
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 corp.alliance.evecorporationinfo_set.filter(corporation_id=settings.CORP_ID).exists() is False:
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)

View File

4
notifications/admin.py Normal file
View File

@ -0,0 +1,4 @@
from django.contrib import admin
from.models import Notification
admin.site.register(Notification)

View File

@ -0,0 +1,4 @@
from .models import Notification
def user_notification_count(request):
return {'notifications':len(Notification.objects.filter(user__id=request.user.id).filter(viewed=False))}

14
notifications/handlers.py Normal file
View File

@ -0,0 +1,14 @@
import logging
from django.contrib.auth.models import User
from .models import Notification
class NotificationHandler(logging.Handler):
def emit(self, record):
for user in User.objects.all():
if user.has_perm('auth.logging_notifications'):
notif = Notification()
notif.user = user
notif.title = "%s [%s:%s]" % (record.levelname, record.funcName, record.lineno)
notif.level = str([item[0] for item in Notification.LEVEL_CHOICES if item[1] == record.levelname][0])
notif.message = record.getMessage()
notif.save()

34
notifications/models.py Normal file
View File

@ -0,0 +1,34 @@
from django.db import models
from django.contrib.auth.models import User
import logging
logger = logging.getLogger(__name__)
class Notification(models.Model):
LEVEL_CHOICES = (
('danger', 'CRITICAL'),
('danger', 'ERROR'),
('warning', 'WARN'),
('info', 'INFO'),
('success', 'DEBUG'),
)
user = models.ForeignKey(User, on_delete=models.CASCADE)
level = models.CharField(choices=LEVEL_CHOICES, max_length=10)
title = models.CharField(max_length=254)
message = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
viewed = models.BooleanField(default=False)
def view(self):
logger.info("Marking notification as viewed: %s" % self)
self.viewed = True
self.save()
def __unicode__(self):
output = "%s: %s" % (self.user, self.title)
return output.encode('utf-8')
def set_level(self, level):
self.level = [item[0] for item in self.LEVEL_CHOICES if item[1] == level][0]

3
notifications/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

31
notifications/views.py Normal file
View File

@ -0,0 +1,31 @@
from django.shortcuts import render, get_object_or_404, redirect
from .models import Notification
from django.contrib.auth.decorators import login_required
import logging
logger = logging.getLogger(__name__)
@login_required
def notification_list(request):
logger.debug("notification_list called by user %s" % request.user)
new_notifs = Notification.objects.filter(user=request.user).filter(viewed=False)
old_notifs = Notification.objects.filter(user=request.user).filter(viewed=True)
logger.debug("User %s has %s unread and %s read notifications" % (request.user, len(new_notifs), len(old_notifs)))
context = {
'read': old_notifs,
'unread': new_notifs,
}
return render(request, 'registered/notification_list.html', context)
@login_required
def notification_view(request, notif_id):
logger.debug("notification_view called by user %s for notif_id %s" % (request.user, notif_id))
notif = get_object_or_404(Notification, pk=notif_id)
if notif.user == request.user:
logger.debug("Providing notification for user %s" % request.user)
context = {'notif': notif}
notif.view()
return render(request, 'registered/notification_view.html', context)
else:
logger.warn("User %s not authorized to view notif_id %s belonging to user %s" % (request.user, notif_id, notif.user))
return redirect('auth_notification_list')

View File

@ -220,7 +220,9 @@ class EveApiManager():
return True return True
except evelink.api.APIError as error: except evelink.api.APIError as error:
logger.exception("APIError occured while checking if id %s is an alliance. Possibly not alliance?" % alliance_id) logger.exception("APIError occured while checking if id %s is an alliance. Possibly not alliance?" % alliance_id)
except KeyError:
logger.debug("Alliance with id %s not found in active alliance list." % alliance_id)
return False
logger.debug("Unable to verify id %s is an an alliance." % alliance_id) logger.debug("Unable to verify id %s is an an alliance." % alliance_id)
return False return False
@ -286,11 +288,11 @@ class EveApiManager():
@staticmethod @staticmethod
def validate_member_api(api_id, api_key): def validate_member_api(api_id, api_key):
if settings.MEMBER_API_ACCOUNT: if settings.MEMBER_API_ACCOUNT:
if EveApiManager.check_api_is_type_account(api_id, api_key) is not True: if EveApiManager.check_api_is_type_account(api_id, api_key) is False:
logger.info("Api id %s is not type account as required for members - failed validation." % api_id) logger.info("Api id %s is not type account as required for members - failed validation." % api_id)
return False return False
if EveApiManager.check_api_is_full(api_id, api_key) is not True: if EveApiManager.check_api_is_full(api_id, api_key) is False:
logger.info("Api id %s does not meet member access mask requirements - failed validation." % api_id) logger.info("Api id %s does not meet member access mask requirements - failed validation." % api_id)
return False return False
return True return True
@ -298,10 +300,10 @@ class EveApiManager():
@staticmethod @staticmethod
def validate_blue_api(api_id, api_key): def validate_blue_api(api_id, api_key):
if settings.BLUE_API_ACCOUNT: if settings.BLUE_API_ACCOUNT:
if EveApiManager.check_api_is_type_account(api_id, api_key) is not True: if EveApiManager.check_api_is_type_account(api_id, api_key) is False:
logger.info("Api id %s is not type account as required for blues - failed validation." % api_id) logger.info("Api id %s is not type account as required for blues - failed validation." % api_id)
return False return False
if EveApiManager.check_blue_api_is_full(api_id, api_key) is not True: if EveApiManager.check_blue_api_is_full(api_id, api_key) is False:
logger.info("Api id %s does not meet minimum blue access mask requirements - failed validation." % api_id) logger.info("Api id %s does not meet minimum blue access mask requirements - failed validation." % api_id)
return False return False
return True return True

View File

@ -47,6 +47,15 @@
<!-- /.navbar-header --> <!-- /.navbar-header -->
<ul class="nav navbar-top-links navbar-right"> <ul class="nav navbar-top-links navbar-right">
{% if notifications %}
<li class="nav-link active"><a href="{% url 'auth_notification_list' %}">
<i class="fa fa-flag"></i></a>
</li>
{% else %}
<li class="nav-link"><a href="{% url 'auth_notification_list' %}">
<i class="fa fa-flag-o"></i></a>
</li>
{% endif %}
{% if user.is_authenticated %} {% if user.is_authenticated %}
<li><a href="{% url 'auth_logout_user' %}">Logout</a></li> <li><a href="{% url 'auth_logout_user' %}">Logout</a></li>
{% else %} {% else %}

View File

@ -0,0 +1,74 @@
{% extends "public/base.html" %}
{% load staticfiles %}
{% block title %}Notifications{% endblock %}
{% block content %}
<div class="col-lg-12">
<h1 class="page-header text-center">Notifications</h1>
<div class="col-lg-12 container" id="example">
<div class="row">
<div class="col-lg-12">
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#unread">Unread <b>({{unread|length}})</b></a></li>
<li><a data-toggle="tab" href="#read">Read <b>({{read|length}})</b></a></li>
</ul>
<div class="tab-content">
<div id="unread" class="tab-pane fade in active">
<div class="panel-body">
<div class="table-responsive">
<table class="table table-condensed table-hover table-striped">
<tr>
<th class="text-center">Timestamp</th>
<th class="text-center">Title</th>
<th class="text-center">View</th>
</tr>
{% for notif in unread %}
<tr class="{{ notif.level }}">
<td class="text-center">{{ notif.timestamp }}</td>
<td class="text-center">{{ notif.title }}</td>
<td class="text-center">
<a href="{% url 'auth_notification_view' notif.id %}">
<button type="button" class="btn btn-success" title="View">
<span class="glyphicon glyphicon-eye-open"></span>
</button>
</a>
</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
<div id="read" class="tab-pane fade">
<div class="panel-body">
<div class="table-responsive">
<table class="table table-condensed table-hover table-striped">
<tr>
<th class="text-center">Timestamp</th>
<th class="text-center">Title</th>
<th class="text-center">View</th>
</tr>
{% for notif in read %}
<tr class="{{ notif.level }}">
<td class="text-center">{{ notif.timestamp }}</td>
<td class="text-center">{{ notif.title }}</td>
<td class="text-center">
<a href="{% url 'auth_notification_view' notif.id %}">
<button type="button" class="btn btn-success" title="View">
<span class="glyphicon glyphicon-eye-open"></span>
</button>
</a>
</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,22 @@
{% extends "public/base.html" %}
{% load staticfiles %}
{% block title %}View Notification{% endblock title %}
{% block page_title %}View Notification{% endblock page_title %}
{% block content %}
<div class="col-lg-12">
<h1 class="page-header text-center">View Notification</h1>
<div class="col-lg-12 container" id="example">
<div class="row">
<div class="col-lg-12">
<div class="panel panel-{{ notif.level }}">
<div class="panel-heading">{{ notif.timestamp }} {{ notif.title }}</div>
<div class="panel-body">{{ notif.message }}</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -27,6 +27,7 @@ def bootstrap_permissions():
Permission.objects.get_or_create(codename="signature_view", content_type=ct, name="signature_view") Permission.objects.get_or_create(codename="signature_view", content_type=ct, name="signature_view")
Permission.objects.get_or_create(codename="optimer_management", content_type=ct, name="optimer_management") Permission.objects.get_or_create(codename="optimer_management", content_type=ct, name="optimer_management")
Permission.objects.get_or_create(codename="optimer_view", content_type=ct, name="optimer_view") Permission.objects.get_or_create(codename="optimer_view", content_type=ct, name="optimer_view")
Permission.objects.get_or_create(codename="logging_notifications", content_type=ct, name="logging_notifications")
Group.objects.get_or_create(name=settings.DEFAULT_AUTH_GROUP) Group.objects.get_or_create(name=settings.DEFAULT_AUTH_GROUP)
Group.objects.get_or_create(name=settings.DEFAULT_BLUE_GROUP) Group.objects.get_or_create(name=settings.DEFAULT_BLUE_GROUP)
logger.info("Bootstrapped permissions for auth and created default groups.") logger.info("Bootstrapped permissions for auth and created default groups.")