use common base class for OAuth1.0 based API interfaces
This commit is contained in:
@@ -243,7 +243,7 @@ class FlickrSearchExtractor(FlickrExtractor):
|
|||||||
return self.api.photos_search(self.search)
|
return self.api.photos_search(self.search)
|
||||||
|
|
||||||
|
|
||||||
class FlickrAPI():
|
class FlickrAPI(oauth.OAuth1API):
|
||||||
"""Minimal interface for the flickr API"""
|
"""Minimal interface for the flickr API"""
|
||||||
API_URL = "https://api.flickr.com/services/rest/"
|
API_URL = "https://api.flickr.com/services/rest/"
|
||||||
API_KEY = "ac4fd7aa98585b9eee1ba761c209de68"
|
API_KEY = "ac4fd7aa98585b9eee1ba761c209de68"
|
||||||
@@ -264,20 +264,7 @@ class FlickrAPI():
|
|||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, extractor):
|
def __init__(self, extractor):
|
||||||
api_key = extractor.config("api-key", self.API_KEY)
|
oauth.OAuth1API.__init__(self, extractor)
|
||||||
api_secret = extractor.config("api-secret", self.API_SECRET)
|
|
||||||
token = extractor.config("access-token")
|
|
||||||
token_secret = extractor.config("access-token-secret")
|
|
||||||
|
|
||||||
if api_key and api_secret and token and token_secret:
|
|
||||||
self.session = oauth.OAuth1Session(
|
|
||||||
api_key, api_secret,
|
|
||||||
token, token_secret,
|
|
||||||
)
|
|
||||||
self.api_key = None
|
|
||||||
else:
|
|
||||||
self.session = extractor.session
|
|
||||||
self.api_key = api_key
|
|
||||||
|
|
||||||
self.maxsize = extractor.config("size-max")
|
self.maxsize = extractor.config("size-max")
|
||||||
if isinstance(self.maxsize, str):
|
if isinstance(self.maxsize, str):
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ class SmugmugPathExtractor(SmugmugExtractor):
|
|||||||
yield from self.album_nodes(node)
|
yield from self.album_nodes(node)
|
||||||
|
|
||||||
|
|
||||||
class SmugmugAPI():
|
class SmugmugAPI(oauth.OAuth1API):
|
||||||
"""Minimal interface for the smugmug API v2"""
|
"""Minimal interface for the smugmug API v2"""
|
||||||
API_DOMAIN = "api.smugmug.com"
|
API_DOMAIN = "api.smugmug.com"
|
||||||
API_KEY = "DFqxg4jf7GrtsQ5PnbNB8899zKfnDrdK"
|
API_KEY = "DFqxg4jf7GrtsQ5PnbNB8899zKfnDrdK"
|
||||||
@@ -179,24 +179,6 @@ class SmugmugAPI():
|
|||||||
"9nMFQm25ndGBzNPnwRDbRnnVBvqt4xTq")
|
"9nMFQm25ndGBzNPnwRDbRnnVBvqt4xTq")
|
||||||
HEADERS = {"Accept": "application/json"}
|
HEADERS = {"Accept": "application/json"}
|
||||||
|
|
||||||
def __init__(self, extractor):
|
|
||||||
api_key = extractor.config("api-key", self.API_KEY)
|
|
||||||
api_secret = extractor.config("api-secret", self.API_SECRET)
|
|
||||||
token = extractor.config("access-token")
|
|
||||||
token_secret = extractor.config("access-token-secret")
|
|
||||||
|
|
||||||
if api_key and api_secret and token and token_secret:
|
|
||||||
self.session = oauth.OAuth1Session(
|
|
||||||
api_key, api_secret,
|
|
||||||
token, token_secret,
|
|
||||||
)
|
|
||||||
self.api_key = None
|
|
||||||
else:
|
|
||||||
self.session = extractor.session
|
|
||||||
self.api_key = api_key
|
|
||||||
|
|
||||||
self.log = extractor.log
|
|
||||||
|
|
||||||
def album(self, album_id, expands=None):
|
def album(self, album_id, expands=None):
|
||||||
return self._expansion("album/" + album_id, expands)
|
return self._expansion("album/" + album_id, expands)
|
||||||
|
|
||||||
|
|||||||
@@ -248,30 +248,15 @@ class TumblrLikesExtractor(TumblrExtractor):
|
|||||||
return self.api.likes(self.blog)
|
return self.api.likes(self.blog)
|
||||||
|
|
||||||
|
|
||||||
class TumblrAPI():
|
class TumblrAPI(oauth.OAuth1API):
|
||||||
"""Minimal interface for the Tumblr API v2"""
|
"""Minimal interface for the Tumblr API v2"""
|
||||||
API_KEY = "O3hU2tMi5e4Qs5t3vezEi6L0qRORJ5y9oUpSGsrWu8iA3UCc3B"
|
API_KEY = "O3hU2tMi5e4Qs5t3vezEi6L0qRORJ5y9oUpSGsrWu8iA3UCc3B"
|
||||||
API_SECRET = "sFdsK3PDdP2QpYMRAoq0oDnw0sFS24XigXmdfnaeNZpJpqAn03"
|
API_SECRET = "sFdsK3PDdP2QpYMRAoq0oDnw0sFS24XigXmdfnaeNZpJpqAn03"
|
||||||
BLOG_CACHE = {}
|
BLOG_CACHE = {}
|
||||||
|
|
||||||
def __init__(self, extractor):
|
def __init__(self, extractor):
|
||||||
api_key = extractor.config("api-key", self.API_KEY)
|
oauth.OAuth1API.__init__(self, extractor)
|
||||||
api_secret = extractor.config("api-secret", self.API_SECRET)
|
|
||||||
token = extractor.config("access-token")
|
|
||||||
token_secret = extractor.config("access-token-secret")
|
|
||||||
|
|
||||||
if api_key and api_secret and token and token_secret:
|
|
||||||
self.session = oauth.OAuth1Session(
|
|
||||||
api_key, api_secret,
|
|
||||||
token, token_secret,
|
|
||||||
)
|
|
||||||
self.api_key = None
|
|
||||||
else:
|
|
||||||
self.session = extractor.session
|
|
||||||
self.api_key = api_key
|
|
||||||
|
|
||||||
self.posts_type = None
|
self.posts_type = None
|
||||||
self.log = extractor.log
|
|
||||||
|
|
||||||
def info(self, blog):
|
def info(self, blog):
|
||||||
"""Return general information about a blog"""
|
"""Return general information about a blog"""
|
||||||
|
|||||||
@@ -22,8 +22,23 @@ import requests.auth
|
|||||||
from . import text
|
from . import text
|
||||||
|
|
||||||
|
|
||||||
|
def nonce(size, alphabet=string.ascii_letters):
|
||||||
|
"""Generate a nonce value with 'size' characters"""
|
||||||
|
return "".join(random.choice(alphabet) for _ in range(size))
|
||||||
|
|
||||||
|
|
||||||
|
def quote(value, quote=urllib.parse.quote):
|
||||||
|
"""Quote 'value' according to the OAuth1.0 standard"""
|
||||||
|
return quote(value, "~")
|
||||||
|
|
||||||
|
|
||||||
|
def concat(*args):
|
||||||
|
"""Concatenate 'args' as expected by OAuth1.0"""
|
||||||
|
return "&".join(quote(item) for item in args)
|
||||||
|
|
||||||
|
|
||||||
class OAuth1Session(requests.Session):
|
class OAuth1Session(requests.Session):
|
||||||
"""Extension to requests.Session objects to support OAuth 1.0"""
|
"""Extension to requests.Session to support OAuth 1.0"""
|
||||||
|
|
||||||
def __init__(self, consumer_key, consumer_secret,
|
def __init__(self, consumer_key, consumer_secret,
|
||||||
token=None, token_secret=None):
|
token=None, token_secret=None):
|
||||||
@@ -42,6 +57,7 @@ class OAuth1Session(requests.Session):
|
|||||||
|
|
||||||
class OAuth1Client(requests.auth.AuthBase):
|
class OAuth1Client(requests.auth.AuthBase):
|
||||||
"""OAuth1.0a authentication"""
|
"""OAuth1.0a authentication"""
|
||||||
|
|
||||||
def __init__(self, consumer_key, consumer_secret,
|
def __init__(self, consumer_key, consumer_secret,
|
||||||
token=None, token_secret=None):
|
token=None, token_secret=None):
|
||||||
|
|
||||||
@@ -86,16 +102,25 @@ class OAuth1Client(requests.auth.AuthBase):
|
|||||||
return quote(base64.b64encode(signature).decode())
|
return quote(base64.b64encode(signature).decode())
|
||||||
|
|
||||||
|
|
||||||
def concat(*args):
|
class OAuth1API():
|
||||||
"""Concatenate 'args'"""
|
"""Base class for OAuth1.0 based API interfaces"""
|
||||||
return "&".join(quote(item) for item in args)
|
API_KEY = None
|
||||||
|
API_SECRET = None
|
||||||
|
|
||||||
|
def __init__(self, extractor):
|
||||||
|
self.log = extractor.log
|
||||||
|
|
||||||
def nonce(size, alphabet=string.ascii_letters):
|
api_key = extractor.config("api-key", self.API_KEY)
|
||||||
"""Generate a nonce value with 'size' characters"""
|
api_secret = extractor.config("api-secret", self.API_SECRET)
|
||||||
return "".join(random.choice(alphabet) for _ in range(size))
|
token = extractor.config("access-token")
|
||||||
|
token_secret = extractor.config("access-token-secret")
|
||||||
|
|
||||||
|
if api_key and api_secret and token and token_secret:
|
||||||
def quote(value, quote=urllib.parse.quote):
|
self.log.debug("Using OAuth1.0 authentication")
|
||||||
"""Quote 'value' according to the OAuth1.0 standard"""
|
self.session = OAuth1Session(
|
||||||
return quote(value, "~")
|
api_key, api_secret, token, token_secret)
|
||||||
|
self.api_key = None
|
||||||
|
else:
|
||||||
|
self.log.debug("Using api_key authentication")
|
||||||
|
self.session = extractor.session
|
||||||
|
self.api_key = api_key
|
||||||
|
|||||||
Reference in New Issue
Block a user