Commit 00f3812c authored by Josh Roesslein's avatar Josh Roesslein
Browse files

Implemented in-memory cache. Tied in cache system into binder.

parent c1aad106
......@@ -10,6 +10,7 @@ __version__ = '1.0'
from models import *
from error import TweepError
from api import API
from cache import *
# Global, unauthenticated instance of API
api = API()
......@@ -12,7 +12,8 @@ from error import TweepError
"""Twitter API"""
class API(object):
def __init__(self, username=None, password=None, host='twitter.com', secure=False,
def __init__(self, username=None, password=None, host='twitter.com',
cache=None, secure=False,
classes={'user': User, 'status': Status,
'direct_message': DirectMessage, 'friendship': Friendship,
'saved_search': SavedSearch, 'search_result': SearchResult}):
......@@ -21,6 +22,7 @@ class API(object):
else:
self._b64up = None
self.host = host
self.cache = cache
self.secure = secure
self.classes = classes
self.username = username
......
......@@ -21,6 +21,20 @@ def bind_api(path, parser, allowed_param=None, method='GET', require_auth=False,
else:
parameters = None
# Build url with parameters
if parameters:
url = '%s?%s' % (path, urllib.urlencode(parameters))
else:
url = path
# Check cache if caching enabled and method is GET
if api.cache and method == 'GET':
cache_result = api.cache.get(url)
if cache_result:
# if cache result found and not expired, return it
print 'hit!'
return cache_result
# Open connection
if host:
_host = host
......@@ -31,12 +45,6 @@ def bind_api(path, parser, allowed_param=None, method='GET', require_auth=False,
else:
conn = httplib.HTTPConnection(_host)
# Build url with parameters
if parameters:
url = '%s?%s' % (path, urllib.urlencode(parameters))
else:
url = path
# Assemble headers
headers = {
'User-Agent': 'tweepy'
......@@ -57,6 +65,10 @@ def bind_api(path, parser, allowed_param=None, method='GET', require_auth=False,
# Pass returned body into parser and return parser output
out = parser(resp.read(), api)
# store result in cache
if api.cache and method == 'GET':
api.cache.store(url, out)
# close connection and return data
conn.close()
return out
......
# Tweepy
# Copyright 2009 Joshua Roesslein
# See LICENSE
import time
import threading
"""Cache interface"""
class Cache(object):
def __init__(self, timeout=60):
"""Init the cache
timeout: number of seconds to keep a cached entry
"""
self.timeout = timeout
def store(self, key, value):
"""Add new record to cache
key: entry key
value: data of entry
"""
raise NotImplemented
def get(self, key):
"""Get cached entry if exists and not expired
key: which entry to get
"""
raise NotImplemented
def cleanup(self):
"""Delete any expired entries in cache."""
raise NotImplemented
def flush(self):
"""Delete all cached entries"""
raise NotImplemented
"""In-memory cache"""
class MemoryCache(Cache):
def __init__(self, timeout=60):
Cache.__init__(self, timeout)
self._entries = {}
self.lock = threading.Lock()
def _is_expired(self, entry):
return (time.time() - entry[0]) >= self.timeout
def store(self, key, value):
with self.lock:
self._entries[key] = (time.time(), value)
def get(self, key):
with self.lock:
# check to see if we have this key
entry = self._entries.get(key)
if not entry:
# no hit, return nothing
return None
# make sure entry is not expired
if self._is_expired(entry):
# entry expired, delete and return nothing
del self._entries[key]
return None
# entry found and not expired, return it
return entry[1]
def cleanup(self):
with self.lock:
for k,v in self._entries.items():
if self._is_expired(v):
del self._entries[k]
def flush(self):
with self.lock:
self._entries.clear()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment