mirror of
https://github.com/nikdoof/test-auth.git
synced 2025-12-14 14:52:15 +00:00
165 lines
5.6 KiB
Python
Executable File
165 lines
5.6 KiB
Python
Executable File
import httplib
|
|
import urllib
|
|
import xml
|
|
import hashlib
|
|
import socket
|
|
from datetime import datetime, timedelta
|
|
from xml.dom import minidom
|
|
from django.db import models
|
|
from eve_api.api_exceptions import APIAuthException, APINoUserIDException
|
|
|
|
# You generally never want to change this unless you have a very good reason.
|
|
API_URL = 'api.eve-online.com'
|
|
|
|
class CachedDocumentManager(models.Manager):
|
|
"""
|
|
This manager handles querying or retrieving CachedDocuments.
|
|
"""
|
|
|
|
def get_document_id(self, url_path, params):
|
|
if params:
|
|
p = params.copy()
|
|
if 'service' in p:
|
|
del p['service']
|
|
paramstr = urllib.urlencode(p)
|
|
else:
|
|
paramstr = ''
|
|
|
|
return hashlib.sha1('%s?%s' % (url_path, paramstr)).hexdigest()
|
|
|
|
def cache_from_eve_api(self, url_path, params):
|
|
"""
|
|
Connect to the EVE API server, send the request, and cache it to
|
|
a CachedDocument. This is typically not something you want to call
|
|
directly. Use api_query().
|
|
"""
|
|
|
|
method = 'GET'
|
|
paramstr = ''
|
|
service = 'auth'
|
|
|
|
if params:
|
|
if 'service' in params:
|
|
service = params['service']
|
|
del params['service']
|
|
paramstr = urllib.urlencode(params)
|
|
|
|
if len(paramstr.strip()) > 0:
|
|
method = 'POST'
|
|
|
|
headers = {"Content-type": "application/x-www-form-urlencoded"}
|
|
conn = httplib.HTTPConnection(API_URL)
|
|
try:
|
|
conn.request(method, url_path, paramstr, headers)
|
|
except socket.error:
|
|
return None
|
|
response = conn.getresponse()
|
|
|
|
if response.status == 200:
|
|
doc_id = self.get_document_id(url_path, params)
|
|
cached_doc, created = self.get_or_create(url_path=doc_id)
|
|
cached_doc.body = unicode(response.read(), 'utf-8')
|
|
cached_doc.time_retrieved = datetime.utcnow()
|
|
|
|
try:
|
|
# Parse the response via minidom
|
|
dom = minidom.parseString(cached_doc.body.encode('utf-8'))
|
|
except xml.parsers.expat.ExpatError:
|
|
cached_doc.cached_until = datetime.utcnow()
|
|
else:
|
|
cached_doc.cached_until = dom.getElementsByTagName('cachedUntil')[0].childNodes[0].nodeValue
|
|
|
|
# If this is user related, write a log instance
|
|
if params and 'userID' in params:
|
|
try:
|
|
v = int(params['userID'])
|
|
except ValueError:
|
|
pass
|
|
else:
|
|
log = ApiAccessLog()
|
|
log.userid = v
|
|
log.service = service
|
|
log.time_access = cached_doc.time_retrieved
|
|
log.document = url_path
|
|
log.save()
|
|
|
|
# Finish up and return the resulting document just in case.
|
|
cached_doc.save()
|
|
cached_doc = self.get(id=cached_doc.pk)
|
|
|
|
return cached_doc
|
|
|
|
def api_query(self, url_path, params=None, no_cache=False, exceptions=True):
|
|
"""
|
|
Transparently handles querying EVE API or retrieving the document from
|
|
the cache.
|
|
|
|
Arguments:
|
|
url_path: (string) Path to the EVE API page to query. For example:
|
|
/eve/ErrorList.xml.aspx
|
|
params: (dictionary/string) A dictionary of extra parameters to include.
|
|
May also be a string representation of
|
|
the query: userID=1&characterID=xxxxxxxx
|
|
"""
|
|
|
|
doc_id = self.get_document_id(url_path, params)
|
|
|
|
doc = None
|
|
if not no_cache:
|
|
try:
|
|
doc = super(CachedDocumentManager, self).get_query_set().get(url_path=doc_id)
|
|
except self.model.DoesNotExist:
|
|
pass
|
|
|
|
# EVE uses UTC.
|
|
current_eve_time = datetime.utcnow()
|
|
|
|
if not doc or not doc.cached_until or current_eve_time > doc.cached_until:
|
|
doc = self.cache_from_eve_api(url_path, params)
|
|
|
|
if doc:
|
|
dom = minidom.parseString(doc.body.encode('utf-8'))
|
|
|
|
if dom:
|
|
error_node = dom.getElementsByTagName('error')
|
|
if error_node and exceptions:
|
|
error_code = error_node[0].getAttribute('code')
|
|
# User specified an invalid userid and/or auth key.
|
|
if error_code == '203':
|
|
raise APIAuthException()
|
|
elif error_code == '106':
|
|
raise APINoUserIDException()
|
|
|
|
return doc
|
|
|
|
class CachedDocument(models.Model):
|
|
"""
|
|
This is a cached XML document from the EVE API.
|
|
"""
|
|
url_path = models.CharField(max_length=255)
|
|
body = models.TextField()
|
|
time_retrieved = models.DateTimeField(blank=True, null=True)
|
|
cached_until = models.DateTimeField(blank=True, null=True)
|
|
|
|
# The custom manager handles the querying.
|
|
objects = CachedDocumentManager()
|
|
|
|
class Meta:
|
|
verbose_name = 'Cached Document'
|
|
verbose_name_plural = 'Cached Documents'
|
|
ordering = ['time_retrieved']
|
|
|
|
class ApiAccessLog(models.Model):
|
|
"""
|
|
Provides a list of API accesses made by applications or Auth
|
|
"""
|
|
userid = models.IntegerField()
|
|
service = models.CharField(max_length=255)
|
|
time_access = models.DateTimeField()
|
|
document = models.CharField(max_length=255)
|
|
|
|
class Meta:
|
|
verbose_name = 'API Access Log'
|
|
verbose_name_plural = 'API Access Logs'
|
|
ordering = ['time_access']
|