Skip to content

Commit

Permalink
Added support for the follow API and fixed issue #2 on bitbucket. Sig…
Browse files Browse the repository at this point in the history
…nificant change.

All API functions return dictionaries.
Google Appengine support is not currently working.
Caching has bugs, and the wrapper defaults to no caching.
CLI tool does not currently support the follow API.
Unit tests coming soon.
  • Loading branch information
Fletcher Tomalty committed Nov 4, 2011
1 parent ec95d41 commit 1b4e4f9
Show file tree
Hide file tree
Showing 6 changed files with 489 additions and 405 deletions.
16 changes: 8 additions & 8 deletions README
Expand Up @@ -29,13 +29,13 @@ $ ./diffbot.py
Usage: diffbot.py: [options] [url]

Options:
-h, --help show this help message and exit
-d, --debug
-v, --verbose
-q, --quiet
-o OFORMAT, --output=OFORMAT
Ouput format (html, raw, json, pretty)
-k KEY Diffbot developer API key
-h, --help show this help message and exit
-d, --debug
-v, --verbose
-q, --quiet
-o OFORMAT, --output=OFORMAT
Ouput format (html, raw, json, pretty)
-k KEY Diffbot developer API key

}}}

Expand All @@ -60,7 +60,7 @@ import diffbot

def main(url):
db = diffbot.DiffBot(dev_token = "mydevtoken")
article = db.get_article(url)
article = db.article(url)
}}}

=== Links and Resources ===
Expand Down
10 changes: 5 additions & 5 deletions diffbot/__init__.py
Expand Up @@ -8,16 +8,16 @@
# URL: <http://nikcub.appspot.com/bsd-license.txt>

"""
py-diffbot
py-diffbot
Python client and library for the Diffbot article API and others.
Python client and library for the Diffbot article API and others.
:copyright: Copyright (C) 2011 Nik Cubrilovic and others, see AUTHORS
:license: new BSD, see LICENSE for more details.
:copyright: Copyright (C) 2011 Nik Cubrilovic and others, see AUTHORS
:license: new BSD, see LICENSE for more details.
"""

__author__ = 'Nik Cubrilovic <nikcub@gmail.com>'
__version__ = '0.0.1'
__version__ = '0.0.2'
__status__ = 'beta'
__date__ = '28th March 2011'

Expand Down
208 changes: 99 additions & 109 deletions diffbot/cache.py
Expand Up @@ -2,153 +2,143 @@
# -*- coding: utf-8 -*-
# vim:ts=4:sw=4:expandtab
"""
py-diffbot - cache.py
py-diffbot - cache.py
Caching handlers with support for file, GAE memcache and python memcache
Caching handlers with support for file, GAE memcache and python memcache
This source file is subject to the new BSD license that is bundled with this
package in the file LICENSE.txt. The license is also available online at the
URL: <http://nikcub.appspot.com/bsd-license.txt>
This source file is subject to the new BSD license that is bundled with this
package in the file LICENSE.txt. The license is also available online at the
URL: <http://nikcub.appspot.com/bsd-license.txt>
:copyright: Copyright (C) 2011 Nik Cubrilovic and others, see AUTHORS
:license: new BSD, see LICENSE for more details.
:copyright: Copyright (C) 2011 Nik Cubrilovic and others, see AUTHORS
:license: new BSD, see LICENSE for more details.
"""

__version__ = '0.0.1'
__version__ = '0.0.2'
__author__ = 'Nik Cubrilovic <nikcub@gmail.com>'


import os, sys, logging, hashlib
import os, logging, hashlib, urllib

try:
from google.appengine.api import memcache
GAE = True
from google.appengine.api import memcache
GAE = True
except ImportError:
GAE = False
try:
import memcache
LOCAL_MEMCACHE = True
except ImportError:
LOCAL_MEMCACHE = False
GAE = False
try:
import memcache
LOCAL_MEMCACHE = True
except ImportError:
LOCAL_MEMCACHE = False

#---------------------------------------------------------------------------
# Handler Classes
# Handler Classes
#---------------------------------------------------------------------------

class CacheHandler(object):

options = None

def __init__(self, options):
"""docstring for __init__"""
self.options = options

def wrap(self, func):
"""docstring for fname"""
def cache(*args, **kwargs):
logging.info("Called fetch function with")
key = self.hash(args[0])
cache_store = self.get(key)
if cache_store:
return cache_store
val = func(*args, **kwargs)
if val:
self.set(key, val)
return val
return cache

def hash(self, key_name):
return hashlib.sha1(key_name).hexdigest()
options = None

def __init__(self, options):
self.options = options

def wrap(self, func):
def cache(url, data):
logging.info("Called fetch function with")
key = self.hash(url + '?' + urllib.urlencode(data))
cache_store = self.get(key)
if cache_store:
return cache_store
val = func(url, data)
if val:
self.set(key, val)
return val
return cache

def hash(self, key):
return hashlib.sha1(key).hexdigest()

class NullHandler(CacheHandler):
"""docstring for NullHandler"""
def __init__(self, options):
return None
def __init__(self, options):
pass

def wrap(self, func):
return func
def wrap(self, func):
return func

class MemcacheHandler(CacheHandler):

def fname(self):
"""docstring for fname"""
pass
def fname(self):
pass

def fname(self):
"""docstring for fname"""
pass
def fname(self):
pass


class GAEMemcacheHandler(CacheHandler):
"""docstring for GAEMemcacheHandler"""
ttl = 60 * 60 * 24 * 4

ttl = 60 * 60 * 24 * 4
def get(self, key):
return memcache.get(key)

def get(self, key):
"""docstring for get"""
return memcache.get(key)

def set(self, key, value):
"""docstring for set"""
return memcache.set(key, value, self.ttl)
def set(self, key, value):
return memcache.set(key, value, self.ttl)


class FileCacheHandler(CacheHandler):
"""docstring for FileCacheHandler"""

cache_folder = None

def __init__(self, options):
if options.has_key('cache_folder'):
cf = options['cache_folder']
if not cf.startswith('/'):
cf = os.path.join(os.path.dirname(__file__), cf)
if os.path.isdir(cf):
self.cache_folder = options['cache_folder']
else:
raise Exception("Not a valid cache folder: %s (got: %s)" % (cf, os.path.isdir(cf)))
else:
import tempfile
self.cache_folder = tempfile.gettempdir()

def get_filepath(self, key):
return os.path.join(self.cache_folder, "%s.txt" % key)

def get(self, key):
file_path = self.get_filepath(key)
if os.path.isfile(file_path):
logging.info("CACHE HIT")
return open(file_path).read()
return False

def set(self, key, value):
file_path = self.get_filepath(key)
try:
f = open(file_path, 'w')
f.write(value)
except Exception, e:
logging.error("Exception: could not write file %s" % (file_path))
logging.exception(e)
return False
return True

cache_folder = None

def __init__(self, options):
if options is not None and options.has_key('cache_folder'):
cf = options['cache_folder']
if not cf.startswith('/'):
cf = os.path.join(os.path.dirname(__file__), cf)
if os.path.isdir(cf):
self.cache_folder = options['cache_folder']
else:
raise Exception("Not a valid cache folder: %s (got: %s)" % (cf, os.path.isdir(cf)))
else:
import tempfile
self.cache_folder = tempfile.gettempdir()

def get_filepath(self, key):
return os.path.join(self.cache_folder, "%s.txt" % key)

def get(self, key):
file_path = self.get_filepath(key)
if os.path.isfile(file_path):
logging.info("CACHE HIT")
return open(file_path).read()
return False

def set(self, key, value):
file_path = self.get_filepath(key)
try:
f = open(file_path, 'w')
f.write(value)
except Exception, e:
logging.error("Exception: could not write file %s" % (file_path))
logging.exception(e)
return False
return True


#---------------------------------------------------------------------------
# Handler Class
# Handler Class
#---------------------------------------------------------------------------


def handler(cache_options = None):
if cache_options:
if cache_options.has_key('handler'):
if cache_options['handler'] == 'memcache' and GAE:
if cache_options:
if cache_options.has_key('handler'):
if cache_options['handler'] == 'memcache' and GAE:
return GAEMemcacheHandler(cache_options)
elif cache_options['handler'] == 'memcache' and LOCAL_MEMCACHE:
return MemcacheHandler(cache_options)
elif cache_options['handler'] == 'file':
return FileCacheHandler(cache_options)
if GAE:
return GAEMemcacheHandler(cache_options)
elif cache_options['handler'] == 'memcache' and LOCAL_MEMCACHE:
if LOCAL_MEMCACHE and cache_options.has_key('memcache_server'):
return MemcacheHandler(cache_options)
elif cache_options['handler'] == 'file':
return FileCacheHandler(cache_options)
if GAE:
return GAEMemcacheHandler(cache_options)
if LOCAL_MEMCACHE and cache_options.has_key('memcache_server'):
return MemcacheHandler(cache_options)
return FileCacheHandler(cache_options)
return NullHandler(cache_options)

0 comments on commit 1b4e4f9

Please sign in to comment.