Skip to content

Commit

Permalink
Beta release.
Browse files Browse the repository at this point in the history
git-svn-id: https://django-eve-proxy.googlecode.com/svn/trunk@2 eae4c5b0-1759-11de-b208-e5a9466b8568
  • Loading branch information
Greg Taylor committed Mar 23, 2009
1 parent 22f18fa commit a0cac05
Show file tree
Hide file tree
Showing 7 changed files with 890 additions and 0 deletions.
674 changes: 674 additions & 0 deletions django-eve-proxy/LICENSE

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions django-eve-proxy/eve_proxy/__init__.py
@@ -0,0 +1,9 @@
VERSION = (0, 1, 'pre')

# Dynamically calculate the version based on VERSION tuple
if len(VERSION)>2 and VERSION[2] is not None:
str_version = "%d.%d_%s" % VERSION[:3]
else:
str_version = "%d.%d" % VERSION[:2]

__version__ = str_version
9 changes: 9 additions & 0 deletions django-eve-proxy/eve_proxy/admin.py
@@ -0,0 +1,9 @@
from django.contrib import admin
from eve_proxy.models import CachedDocument

class CachedDocumentAdmin(admin.ModelAdmin):
model = CachedDocument
list_display = ('url_path', 'time_retrieved', 'cached_until')
verbose_name = 'Cached Document'
verbose_name_plural = 'Cached Documents'
admin.site.register(CachedDocument, CachedDocumentAdmin)
94 changes: 94 additions & 0 deletions django-eve-proxy/eve_proxy/models.py
@@ -0,0 +1,94 @@
import httplib
import urllib
from datetime import datetime, timedelta
from xml.dom import minidom
from django.db import models

# 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 cache_from_eve_api(self, cached_doc, 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().
"""
headers = {"Content-type": "application/x-www-form-urlencoded"}
# This is the connection to the EVE API server.
conn = httplib.HTTPConnection(API_URL)
# Combine everything into an HTTP request.
conn.request("POST", url_path, params, headers)
# Retrieve the response from the server.
response = conn.getresponse()
# Save the response (an XML document) to the CachedDocument.
cached_doc.body = response.read()

# Parse the response via minidom
dom = minidom.parseString(cached_doc.body)
# Set the CachedDocument's time_retrieved and cached_until times based
# on the values in the XML response. This will be used in future
# requests to see if the CachedDocument can be retrieved directly or
# if it needs to be re-cached.
cached_doc.time_retrieved = dom.getElementsByTagName('currentTime')[0].childNodes[0].nodeValue
cached_doc.cached_until = dom.getElementsByTagName('cachedUntil')[0].childNodes[0].nodeValue

# Finish up and return the resulting document just in case.
cached_doc.save()
return cached_doc

def api_query(self, url_path, params):
"""
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
"""
if type({}) == type(params):
# If 'params' is a dictionary, convert it to a URL string.
params = urllib.urlencode(params)
elif params == None or params.strip() == '':
# For whatever reason, EVE API freaks out if there are no parameters.
# Add a bogus parameter if none are specified. I'm sure there's a
# better fix for this.
params = 'odd_parm=1'

# Combine the URL path and the parameters to create the full query.
query_name = '%s?%s' % (url_path, params)

# Retrieve or create a new CachedDocument based on the full URL
# and parameters.
cached_doc, created = self.get_or_create(url_path=query_name)

# EVE uses UTC.
current_eve_time = datetime.utcnow()

# Figure out if we need hit EVE API and re-cache, or just pull from
# the local cache (based on cached_until).
if created or \
cached_doc.cached_until == None or \
current_eve_time > cached_doc.cached_until:
# Cache from EVE API
self.cache_from_eve_api(cached_doc, url_path, params)

return cached_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()
8 changes: 8 additions & 0 deletions django-eve-proxy/eve_proxy/urls.py
@@ -0,0 +1,8 @@
from django.conf.urls.defaults import *

urlpatterns = patterns('eve_proxy.views',
# This view can be used just like EVE API's http://api.eve-online.com.
# Any parameters or URL paths are sent through the cache system and
# forwarded to the EVE API site as needed.
url(r'^', 'retrieve_xml', name='eve_proxy-retrieve_xml'),
)
17 changes: 17 additions & 0 deletions django-eve-proxy/eve_proxy/views.py
@@ -0,0 +1,17 @@
from django.http import HttpResponse
from eve_proxy.models import CachedDocument

def retrieve_xml(request):
"""
A view that forwards EVE API requests through the cache system, either
retrieving a cached document or querying and caching as needed.
"""
# This is the URL path (minus the parameters).
url_path = request.META['PATH_INFO']
# The parameters attached to the end of the URL path.
params = request.META['QUERY_STRING']
# The query system will retrieve a cached_doc that was either previously
# or newly cached depending on cache intervals.
cached_doc = CachedDocument.objects.api_query(url_path, params)
# Return the document's body as XML.
return HttpResponse(cached_doc.body, mimetype='text/xml')
79 changes: 79 additions & 0 deletions django-eve-proxy/setup.py
@@ -0,0 +1,79 @@
"""
Based entirely on Django's own ``setup.py``.
"""
import os
from distutils.command.install import INSTALL_SCHEMES
from distutils.core import setup

def fullsplit(path, result=None):
"""
Split a pathname into components (the opposite of os.path.join) in a
platform-neutral way.
"""
if result is None:
result = []
head, tail = os.path.split(path)
if head == '':
return [tail] + result
if head == path:
return result
return fullsplit(head, [tail] + result)

# Tell distutils to put the data_files in platform-specific installation
# locations. See here for an explanation:
# http://groups.google.com/group/comp.lang.python/browse_thread/thread/35ec7b2fed36eaec/2105ee4d9e8042cb
for scheme in INSTALL_SCHEMES.values():
scheme['data'] = scheme['purelib']

# Compile the list of packages available, because distutils doesn't have
# an easy way to do this.
packages, data_files = [], []
root_dir = os.path.dirname(__file__)
extensions_dir = os.path.join(root_dir, 'eve_proxy')
pieces = fullsplit(root_dir)
if pieces[-1] == '':
len_root_dir = len(pieces) - 1
else:
len_root_dir = len(pieces)

for dirpath, dirnames, filenames in os.walk(extensions_dir):
# Ignore dirnames that start with '.'
for i, dirname in enumerate(dirnames):
if dirname.startswith('.'):
del dirnames[i]
#if 'conf' in dirpath:
# print dirpath
if '__init__.py' in filenames and not 'conf' in dirpath:
packages.append('.'.join(fullsplit(dirpath)[len_root_dir:]))
elif filenames:
data_files.append([dirpath, [os.path.join(dirpath, f) for f in filenames]])

version = __import__('eve_proxy').__version__

setup(
name = 'django-eve-proxy',
version = version,
description = "A Django-based EVE API proxy.",
long_description = """django-eve-proxy transparently handles requests to
the EVE API from Python code or via HTTP. This allows developers to
provide a restricted or global EVE API HTTP proxy, or access the EVE API
via the CachedDocument python object.
See the project page for more information:
http://code.google.com/p/django-eve-proxy/""",
author = 'Gregory Taylor',
author_email = 'gtaylor@l11solutions.com',
url = 'http://code.google.com/p/django-eve-proxy/',
license = 'GPL',
platforms = ['any'],
packages = packages,
data_files = data_files,
classifiers = ['Development Status :: 4 - Beta',
'Environment :: Web Environment',
'Framework :: Django',
'Intended Audience :: Developers',
'License :: OSI Approved :: GNU General Public License (GPL)',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Topic :: Utilities'],
)

0 comments on commit a0cac05

Please sign in to comment.