forked from gtaylor/django-eve-proxy
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
Showing
7 changed files
with
890 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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'), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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'], | ||
) | ||
|