def authenticate(self, access_token=None, access_token_secret=None): """Authenticate client to query requiring authorization""" self.session = GoodreadsSession(self.client_key, self.client_secret, access_token, access_token_secret) if access_token and access_token_secret: self.session.oauth_resume() else: url = self.session.oauth_init() webbrowser.open(url) while raw_input("Have you authorized me? (y/n)") != 'y': pass self.session.oauth_finalize()
def authenticate(self, access_token=None, access_token_secret=None): """ Go through Open Auththenication process. """ self.session = GoodreadsSession(self.client_id, self.client_secret, access_token, access_token_secret) if access_token and access_token_secret: self.session.oath_resume() else: # Access not yet granted, allow via browser url = self.session.oath_start() webbrowser.open(url) while raw_input('Have you authorized me? (y/n) ') != 'y': pass self.session.oauth_finish()
class Client: """ A client for interacting with Goodreads resources.""" host = "https://www.goodreads.com/" session = None def __init__(self, **kwargs): """ Create a client instance using the provided options. The passed options should be passed as kwargs. """ self.client_id = kwargs.get('client_id') self.client_secret = kwargs.get('client_secret') self.query_dict = {'key': self.client_id} def authenticate(self, access_token=None, access_token_secret=None): """ Go through Open Auththenication process. """ self.session = GoodreadsSession(self.client_id, self.client_secret, access_token, access_token_secret) if access_token and access_token_secret: self.session.oath_resume() else: # Access not yet granted, allow via browser url = self.session.oath_start() webbrowser.open(url) while raw_input('Have you authorized me? (y/n) ') != 'y': pass self.session.oauth_finish() def get_access_tokens(): """ Return access tokens for storage, so that sessions can be resumed easily. Returns: (access_token, access_token_secret) """ if not self.session: raise GoodreadsSessionError("No authenticated session.") return self.session.access_token, self.session.access_token_secret def book_title(self, **query_dict): """ Get information about a book. Input Example: {'author' : 'Chuck Palahniuk', 'title' : 'Fight Club'} """ goodreads_request = GoodreadsRequest("book/title.xml", query_dict, self) response = goodreads_request.request() return Book(response['book']) def author_by_id(self, **query_dict): """ Get information about an author from their id. Input example: { 'id' : '2546' } """ goodreads_request = GoodreadsRequest("author/show.xml", query_dict, self) response = goodreads_request.request() return Author(response['author']) def get_author_id(self, name): """ Get the id of an author given the name.""" name = urllib.quote_plus(name) goodreads_request = GoodreadsRequest("api/author_url/" + name, {}, self) response = goodreads_request.request() return response['author']['@id'] def get_book_id(self, isbn): """ Get book id given the isbn. """ goodreads_request = GoodreadsRequest("book/isbn_to_id/" + isbn, {}, self) response = goodreads_request.request(return_raw=True) return response def get_friends(self, user_id, num=MAX_INT): """ Get pages of user's friends list. (30 per page) Returns: ((id, name),) """ if not self.session: raise GoodreadsSessionError("No authenticated session.") # Iterate through pages friends = [] page, end, total = 1, 0, 1 while end < num and end < total: data_dict = self.session.get('friend/user/' + user_id, { 'format': 'xml', 'page': str(page) }) data_dict = data_dict['friends'] # Check to see if there is 'user' (friend) data if len(data_dict) == 3: break # No friends :( else: # Update progress end = int(data_dict['@end']) total = int(data_dict['@total']) page += 1 # Add page's list to total friends.extend([(user['id'], user['name']) for user in data_dict['user']]) # Return compiled list of friends return friends def get_auth_user(self): """ Get the OAuthenticated user id and name """ if not self.session: raise GoodreadsSessionError("No authenticated session.") data_dict = self.session.get('api/auth_user', {'format': 'xml'}) # Parse response user_id = data_dict['user']['@id'] name = data_dict['user']['name'] return user_id, name def compare_books(self, user_id): """ Compare books between the authenticated user and another. """ if not self.session: raise GoodreadsSessionError("No authenticated session.") data_dict = self.session.get('user/compare/' + user_id, {'format': 'xml'}) return Comparison(data_dict['compare'])
class GoodreadsClient(): base_url = "http://www.goodreads.com/" def __init__(self, client_key, client_secret): """Initialize the client""" self.client_key = client_key self.client_secret = client_secret @property def query_dict(self): return {'key': self.client_key} def authenticate(self, access_token=None, access_token_secret=None): """Authenticate client to query requiring authorization""" self.session = GoodreadsSession(self.client_key, self.client_secret, access_token, access_token_secret) if access_token and access_token_secret: self.session.oauth_resume() else: url = self.session.oauth_init() webbrowser.open(url) time.sleep(3) #while raw_input("Have you authorized me? (y/n)") != 'y': # pass self.session.oauth_finalize() def auth_user(self): """Return user who authorized OAuth""" if not hasattr(self, 'session'): raise GoodreadsClientException("No authenticated session") resp = self.session.get("api/auth_user", {}) user_id = resp['user']['@id'] return self.user(user_id) def request(self, *args, **kwargs): """Create a GoodreadsRequest object and make that request""" req = GoodreadsRequest(self, *args, **kwargs) return req.request() def request_oauth(self, *args, **kwargs): resp = self.session.get(*args, **kwargs) return resp def user(self, user_id=None, username=None): """Get info about a member by id or username. If user_id or username not provided, the function returns the authorized user """ if not (user_id or username): return self.auth_user() resp = self.request("user/show", {'id': user_id, 'username': username}) return GoodreadsUser(resp['user'], self) def author(self, author_id): """Get info about an author""" resp = self.request("author/show", {'id': author_id}) return GoodreadsAuthor(resp['author'], self) def find_author(self, author_name): """Find an author by name""" resp = self.request("api/author_url/%s" % author_name, {}) return self.author(resp['author']['@id']) if 'author' in resp else None def book(self, book_id=None, isbn=None): """Get info about a book""" if book_id: resp = self.request("book/show", {'id': book_id}) return GoodreadsBook(resp['book'], self) elif isbn: resp = self.request("book/isbn", {'isbn': isbn}) return GoodreadsBook(resp['book'], self) else: raise GoodreadsClientException("book id or isbn required") def search_books(self, q, page=1, search_field='all'): """Get the most popular books for the given query. This will search all books in the title/author/ISBN fields and show matches, sorted by popularity on Goodreads. :param q: query text :param page: which page to return (default 1) :param search_fields: field to search, one of 'title', 'author' or 'genre' (default is 'all') """ resp = self.request("search/index.xml", {'q': q, 'page': page, 'search[field]': search_field}) works = resp['search']['results']['work'] # If there's only one work returned, put it in a list. if type(works) == collections.OrderedDict: works = [works] return [self.book(work['best_book']['id']['#text']) for work in works] def group(self, group_id): """Get info about a group""" resp = self.request("group/show", {'id': group_id}) return GoodreadsGroup(resp['group']) def owned_book(self, owned_book_id): """Get info about an owned book, given its id""" resp = self.session.get("owned_books/show/%s.xml" % owned_book_id, {}) return GoodreadsOwnedBook(resp['owned_book']['owned_book']) def find_groups(self, query, page=1): """Find a group based on the query""" resp = self.request("group/search.xml", {'q': query, 'page': page}) return resp['groups']['list']['group'] def book_review_stats(self, isbns): """Get review statistics for books given a list of ISBNs""" resp = self.request("book/review_counts.json", {'isbns': ','.join(isbns)}, req_format='json') return resp['books'] def list_comments(self, comment_type, resource_id, page=1): """List comments on a subject. comment_type should be one of 'author_blog_post', 'blog', 'book_news_post', 'chapter', 'comment', 'community_answer', 'event_response', 'fanship', 'friend', 'giveaway', 'giveaway_request', 'group_user', 'interview', 'librarian_note', 'link_collection', 'list', 'owned_book', 'photo', 'poll', 'poll_vote', 'queued_item', 'question', 'question_user_stat', 'quiz', 'quiz_score', 'rating', 'read_status', 'recommendation', 'recommendation_request', 'review', 'topic', 'user', 'user_challenge', 'user_following', 'user_list_challenge', 'user_list_vote', 'user_quote', 'user_status', 'video'. """ resp = self.request("%s/%s/comments" % (comment_type, resource_id), {'format': 'xml'}) return [GoodreadsComment(comment_dict) for comment_dict in resp['comments']['comment']] def list_events(self, postal_code): """Show events near a location specified with the postal code""" resp = self.request("event/index.xml", {'search[postal_code]': postal_code}) return [GoodreadsEvent(e) for e in resp['events']['event']] def recent_reviews(self): """Get the recent reviews from all members""" resp = self.request("/review/recent_reviews.xml", {}) return [GoodreadsReview(r) for r in resp['reviews']['review']] def review(self, review_id): """Get a review""" resp = self.request("/review/show.xml", {'id': review_id}) return GoodreadsReview(resp['review'])
class GoodreadsClient(): base_url = "http://www.goodreads.com/" def __init__(self, client_key, client_secret): """Initialize the client""" self.client_key = client_key self.client_secret = client_secret @property def query_dict(self): return {'key': self.client_key} def authenticate(self, access_token=None, access_token_secret=None): """Authenticate client to query requiring authorization""" self.session = GoodreadsSession(self.client_key, self.client_secret, access_token, access_token_secret) if access_token and access_token_secret: self.session.oauth_resume() else: url = self.session.oauth_init() webbrowser.open(url) while raw_input("Have you authorized me? (y/n)") != 'y': pass self.session.oauth_finalize() def auth_user(self): """Return user who authorized OAuth""" if not hasattr(self, 'session'): raise GoodreadsClientException("No authenticated session") resp = self.session.get("api/auth_user", {}) user_id = resp['user']['@id'] return self.user(user_id) def request(self, *args, **kwargs): """Create a GoodreadsRequest object and make that request""" req = GoodreadsRequest(self, *args, **kwargs) return req.request() def request_oauth(self, *args, **kwargs): resp = self.session.get(*args, **kwargs) return resp def user(self, user_id=None, username=None): """Get info about a member by id or username. If user_id or username not provided, the function returns the authorized user """ if not (user_id or username): return self.auth_user() resp = self.request("user/show", {'id': user_id, 'username': username}) return GoodreadsUser(resp['user'], self) def author(self, author_id): """Get info about an author""" resp = self.request("author/show", {'id': author_id}) return GoodreadsAuthor(resp['author'], self) def find_author(self, author_name): """Find an author by name""" resp = self.request("api/author_url/%s" % author_name, {}) return self.author(resp['author']['@id']) if 'author' in resp else None def book(self, book_id=None, isbn=None): """Get info about a book""" if book_id: resp = self.request("book/show", {'id': book_id}) return GoodreadsBook(resp['book'], self) elif isbn: resp = self.request("book/isbn", {'isbn': isbn}) return GoodreadsBook(resp['book'], self) else: raise GoodreadsClientException("book id or isbn required") def search_books(self, q, page=1, search_field='all'): """Get the most popular books for the given query. This will search all books in the title/author/ISBN fields and show matches, sorted by popularity on Goodreads. :param q: query text :param page: which page to return (default 1) :param search_fields: field to search, one of 'title', 'author' or 'genre' (default is 'all') """ resp = self.request("search/index.xml", { 'q': q, 'page': page, 'search[field]': search_field }) works = resp['search']['results']['work'] # If there's only one work returned, put it in a list. if type(works) == collections.OrderedDict: works = [works] return [self.book(work['best_book']['id']['#text']) for work in works] def group(self, group_id): """Get info about a group""" resp = self.request("group/show", {'id': group_id}) return GoodreadsGroup(resp['group']) def owned_book(self, owned_book_id): """Get info about an owned book, given its id""" resp = self.session.get("owned_books/show/%s.xml" % owned_book_id, {}) return GoodreadsOwnedBook(resp['owned_book']['owned_book']) def find_groups(self, query, page=1): """Find a group based on the query""" resp = self.request("group/search.xml", {'q': query, 'page': page}) return resp['groups']['list']['group'] def book_review_stats(self, isbns): """Get review statistics for books given a list of ISBNs""" resp = self.request("book/review_counts.json", {'isbns': ','.join(isbns)}, req_format='json') return resp['books'] def list_comments(self, comment_type, resource_id, page=1): """List comments on a subject. comment_type should be one of 'author_blog_post', 'blog', 'book_news_post', 'chapter', 'comment', 'community_answer', 'event_response', 'fanship', 'friend', 'giveaway', 'giveaway_request', 'group_user', 'interview', 'librarian_note', 'link_collection', 'list', 'owned_book', 'photo', 'poll', 'poll_vote', 'queued_item', 'question', 'question_user_stat', 'quiz', 'quiz_score', 'rating', 'read_status', 'recommendation', 'recommendation_request', 'review', 'topic', 'user', 'user_challenge', 'user_following', 'user_list_challenge', 'user_list_vote', 'user_quote', 'user_status', 'video'. """ resp = self.request("%s/%s/comments" % (comment_type, resource_id), {'format': 'xml'}) return [ GoodreadsComment(comment_dict) for comment_dict in resp['comments']['comment'] ] def list_events(self, postal_code): """Show events near a location specified with the postal code""" resp = self.request("event/index.xml", {'search[postal_code]': postal_code}) return [GoodreadsEvent(e) for e in resp['events']['event']] def recent_reviews(self): """Get the recent reviews from all members""" resp = self.request("/review/recent_reviews.xml", {}) return [GoodreadsReview(r) for r in resp['reviews']['review']] def review(self, review_id): """Get a review""" resp = self.request("/review/show.xml", {'id': review_id}) return GoodreadsReview(resp['review'])
class Client: """ A client for interacting with Goodreads resources.""" host = "https://www.goodreads.com/" session = None def __init__(self, **kwargs): """ Create a client instance using the provided options. The passed options should be passed as kwargs. """ self.client_id = kwargs.get('client_id') self.client_secret = kwargs.get('client_secret') self.query_dict = { 'key' : self.client_id } def authenticate(self, access_token=None, access_token_secret=None): """ Go through Open Auththenication process. """ self.session = GoodreadsSession(self.client_id, self.client_secret, access_token, access_token_secret) if access_token and access_token_secret: self.session.oath_resume() else: # Access not yet granted, allow via browser url = self.session.oath_start() webbrowser.open(url) while raw_input('Have you authorized me? (y/n) ') != 'y': pass self.session.oauth_finish() def get_access_tokens(): """ Return access tokens for storage, so that sessions can be resumed easily. Returns: (access_token, access_token_secret) """ if not self.session: raise GoodreadsSessionError("No authenticated session.") return self.session.access_token, self.session.access_token_secret def book_title(self, **query_dict): """ Get information about a book. Input Example: {'author' : 'Chuck Palahniuk', 'title' : 'Fight Club'} """ goodreads_request = GoodreadsRequest("book/title.xml", query_dict, self) response = goodreads_request.request() return Book(response['book']) def author_by_id(self, **query_dict): """ Get information about an author from their id. Input example: { 'id' : '2546' } """ goodreads_request = GoodreadsRequest("author/show.xml", query_dict, self) response = goodreads_request.request() return Author(response['author']) def get_author_id(self, name): """ Get the id of an author given the name.""" name = urllib.quote_plus(name) goodreads_request = GoodreadsRequest("api/author_url/"+name, {}, self) response = goodreads_request.request() return response['author']['@id'] def get_book_id(self, isbn): """ Get book id given the isbn. """ goodreads_request = GoodreadsRequest("book/isbn_to_id/"+isbn, {}, self) response = goodreads_request.request(return_raw=True) return response def get_friends(self, user_id, num=MAX_INT): """ Get pages of user's friends list. (30 per page) Returns: ((id, name),) """ if not self.session: raise GoodreadsSessionError("No authenticated session.") # Iterate through pages friends = [] page, end, total = 1, 0, 1 while end < num and end < total: data_dict = self.session.get('friend/user/'+user_id, {'format':'xml', 'page':str(page)}) data_dict = data_dict['friends'] # Check to see if there is 'user' (friend) data if len(data_dict) == 3: break # No friends :( else: # Update progress end = int(data_dict['@end']) total = int(data_dict['@total']) page += 1 # Add page's list to total friends.extend([(user['id'], user['name']) for user in data_dict['user']]) # Return compiled list of friends return friends def get_auth_user(self): """ Get the OAuthenticated user id and name """ if not self.session: raise GoodreadsSessionError("No authenticated session.") data_dict = self.session.get('api/auth_user', {'format':'xml'}) # Parse response user_id = data_dict['user']['@id'] name = data_dict['user']['name'] return user_id, name def compare_books(self, user_id): """ Compare books between the authenticated user and another. """ if not self.session: raise GoodreadsSessionError("No authenticated session.") data_dict = self.session.get('user/compare/'+user_id, {'format':'xml'}) return Comparison(data_dict['compare'])