def save_data(self, token, trigger_id, **data): """ let's save the data """ if token and 'link' in data and data['link'] is not None and len(data['link']) > 0: # get the data of this trigger trigger = Readability.objects.get(trigger_id=trigger_id) token_key, token_secret = token.split('#TH#') readability_instance = ReaderClient(self.consumer_key, self.consumer_secret, token_key, token_secret) bookmark_id = readability_instance.add_bookmark(url=data['link']) if trigger.tag is not None and len(trigger.tag) > 0: try: readability_instance.add_tags_to_bookmark( bookmark_id, tags=(trigger.tag.lower())) sentence = str('readability {} created item id {}').format( data['link'], bookmark_id) logger.debug(sentence) except Exception as e: logger.critical(e) else: sentence = "no token or link provided for trigger ID {} " logger.critical(sentence.format(trigger_id))
class ReaderClientNoBookmarkTest(TestCase): """Tests for the Readability ReaderClient class that need no bookmarks. """ def setUp(self): """Need to get a token for each test. """ token_pair = xauth(CONSUMER_KEY, CONSUMER_SECRET, USERNAME, PASSWORD) self.token_key = token_pair[0] self.token_secret = token_pair[1] self.base_client = ReaderClient(CONSUMER_KEY, CONSUMER_SECRET, self.token_key, self.token_secret) def test_get_article(self): """Test the `get_article` method. """ article_id = 'lun3elns' response = self.base_client.get_article(article_id) self.assertEqual(response.status, 200) self.assertTrue(isinstance(response.content, dict)) # spot check some keys some_expected_keys = set(['direction', 'title', 'url', 'excerpt', 'content', 'processed', 'short_url', 'date_published']) keys_set = set(response.content.keys()) self.assertTrue(some_expected_keys.issubset(keys_set)) def test_get_article_404(self): """Try getting an article that doesn't exist. """ article_id = 1 response = self.base_client.get_article(article_id) self.assertEqual(response.status, 404) self.assertTrue(isinstance(response.content, dict)) self.assertTrue('error_message' in response.content) def test_get_user(self): """Test getting user data """ user_response = self.base_client.get_user() self.assertEqual(user_response.status, 200) some_expected_keys = set(['username', 'first_name', 'last_name', 'date_joined', 'email_into_address']) received_keys = set(user_response.content.keys()) self.assertTrue(some_expected_keys.issubset(received_keys)) def _test_get_tags(self): """Test getting tags. """ tag_response = self.base_client.get_tags() self.assertEqual(tag_response.status, 200) self.assertTrue('tags' in tag_response.content) self.assertTrue(len(tag_response.content['tags']) > 0)
def setUp(self): """Need to get a token for each test. """ token_pair = xauth(CONSUMER_KEY, CONSUMER_SECRET, USERNAME, PASSWORD) self.token_key = token_pair[0] self.token_secret = token_pair[1] self.base_client = ReaderClient(CONSUMER_KEY, CONSUMER_SECRET, self.token_key, self.token_secret)
class ReaderClientNoBookmarkTest(unittest.TestCase): """ Tests for the Readability ReaderClient class that need no bookmarks. """ def setUp(self): """ Need to get a token for each test. """ token_key, token_secret = xauth() self.reader_client = ReaderClient(token_key, token_secret) def test_get_article(self): """ Test the `get_article` method. """ article_id = 'orrspy2p' response = self.reader_client.get_article(article_id) self.assertEqual(response.status_code, 200) # spot check some keys some_expected_keys = set(['direction', 'title', 'url', 'excerpt', 'content', 'processed', 'short_url', 'date_published']) keys_set = set(response.json().keys()) self.assertTrue(some_expected_keys.issubset(keys_set)) def test_get_article_404(self): """ Try getting an article that doesn't exist. """ article_id = 'antidisestablishmentarianism' response = self.reader_client.get_article(article_id) self.assertEqual(response.status_code, 404) def test_get_user(self): """ Test getting user data """ user_response = self.reader_client.get_user() self.assertEqual(user_response.status_code, 200) some_expected_keys = set(['username', 'first_name', 'last_name', 'date_joined', 'email_into_address']) received_keys = set(user_response.json().keys()) self.assertTrue(some_expected_keys.issubset(received_keys)) def test_get_empty_tags(self): """ Test getting an empty set of tags. Since there are no bookmarks present in this test, there should be no tags. """ tag_response = self.reader_client.get_tags() self.assertEqual(tag_response.status_code, 200) response_json = tag_response.json() self.assertTrue('tags' in response_json) self.assertEqual(len(response_json['tags']), 0)
def __init__(self, token=None): base = 'https://www.readability.com' self.AUTH_URL = '{}/api/rest/v1/oauth/authorize/'.format(base) self.REQ_TOKEN = '{}/api/rest/v1/oauth/request_token/'.format(base) self.ACC_TOKEN = '{}/api/rest/v1/oauth/access_token/'.format(base) self.consumer_key = settings.TH_READABILITY['consumer_key'] self.consumer_secret = settings.TH_READABILITY['consumer_secret'] if token: token_key, token_secret = token.split('#TH#') self.client = ReaderClient(token_key, token_secret, self.consumer_key, self.consumer_secret)
def setUp(self): """Get a client and add a bookmark """ token_pair = xauth(CONSUMER_KEY, CONSUMER_SECRET, USERNAME, PASSWORD) self.token_key = token_pair[0] self.token_secret = token_pair[1] self.base_client = ReaderClient(CONSUMER_KEY, CONSUMER_SECRET, self.token_key, self.token_secret) self.url = 'http://www.theatlantic.com/technology/archive/2013/01/the-never-before-told-story-of-the-worlds-first-computer-art-its-a-sexy-dame/267439/' add_response = self.base_client.add_bookmark(self.url) self.assertEqual(add_response.status, 202)
def setUp(self): """ Need to get a token for each test. """ token_key, token_secret = xauth() self.reader_client = ReaderClient(token_key, token_secret)
def setUp(self): """ Add a few bookmarks. """ token_key, token_secret = xauth() self.reader_client = ReaderClient(token_key=token_key, token_secret=token_secret) self.urls = [ 'http://www.theatlantic.com/technology/archive/2013/01/the-never-before-told-story-of-the-worlds-first-computer-art-its-a-sexy-dame/267439/', 'http://www.theatlantic.com/business/archive/2013/01/why-smart-poor-students-dont-apply-to-selective-colleges-and-how-to-fix-it/272490/', ] self.favorite_urls = [ 'http://www.theatlantic.com/sexes/archive/2013/01/the-lonely-existence-of-mel-feit-mens-rights-advocate/267413/', 'http://www.theatlantic.com/technology/archive/2013/01/women-in-combat-an-idea-whose-time-has-come-aided-by-technology/272483/' ] self.archive_urls = [ 'http://www.theatlantic.com/business/archive/2013/01/what-economics-can-and-cant-tell-us-about-the-legacy-of-legal-abortion/267459/', 'http://www.theatlantic.com/business/archive/2013/01/5-ways-to-understand-just-how-absurd-spains-26-unemployment-rate-is/272502/' ] self.all_urls = self.urls + self.favorite_urls + self.archive_urls for url in self.urls: response = self.reader_client.add_bookmark(url) self.assertTrue(response.status_code in [201, 202]) for url in self.favorite_urls: response = self.reader_client.add_bookmark(url, favorite=True) self.assertTrue(response.status_code in [201, 202]) for url in self.archive_urls: response = self.reader_client.add_bookmark(url, archive=True) self.assertTrue(response.status_code in [201, 202])
def process_data(self, token, trigger_id, date_triggered): """ get the data from the service :param trigger_id: trigger ID to process :param date_triggered: the date of the last trigger :type trigger_id: int :type date_triggered: datetime :return: list of data found from the date_triggered filter :rtype: list """ data = [] if token is not None: token_key, token_secret = token.split('#TH#') client = ReaderClient(self.consumer_key, self.consumer_secret, token_key, token_secret) bookmarks = client.get_bookmarks( added_since=date_triggered).content for bookmark in bookmarks.values(): for b in bookmark: if 'article' in b: title = '' if 'title' in b['article']: title = b['article']['title'] link = '' if 'url' in b['article']: link = b['article']['url'] content = '' if 'excerpt' in b['article']: content = b['article']['excerpt'] data.append({ 'title': title, 'link': link, 'content': content }) return data
def create_client(self): """ Connect to Readability API (http://readability-python-library.readthedocs.org/en/latest/clients.html#readability.ReaderClient) """ rdb_client = ReaderClient(CONSUMER_KEY, CONSUMER_SECRET, self.token[0], self.token[1]) return rdb_client
def __init__(self, token=None, **kwargs): super(ServiceReadability, self).__init__(token, **kwargs) base = 'https://www.readability.com' self.AUTH_URL = '{}/api/rest/v1/oauth/authorize/'.format(base) self.REQ_TOKEN = '{}/api/rest/v1/oauth/request_token/'.format(base) self.ACC_TOKEN = '{}/api/rest/v1/oauth/access_token/'.format(base) self.consumer_key = settings.TH_READABILITY['consumer_key'] self.consumer_secret = settings.TH_READABILITY['consumer_secret'] self.token = token self.service = 'ServiceReadability' self.oauth = 'oauth1' kwargs = { 'consumer_key': self.consumer_key, 'consumer_secret': self.consumer_secret } if token: token_key, token_secret = self.token.split('#TH#') self.client = ReaderClient(token_key, token_secret, **kwargs)
def actualizar(): cred=getAuth() # If no client credentials are passed to ReaderClient's constructor, they # will be looked for in your environment variables """ coneccion = pymongo.MongoClient("localhost") db = coneccion.readability db.drop_collection("bookmarks") datos=db.bookmarks""" client = ReaderClient(token_key=cred[0],token_secret=cred[1],consumer_key=consumer_key,consumer_secret=consumer_secret) print client bookmarks_response = client.get_bookmarks() dic=bookmarks_response.json() for k in dic["bookmarks"]: print k["article"]["title"]
def setUp(self): """ Get a client and add a bookmark """ token_key, token_secret = xauth() self.reader_client = ReaderClient(token_key=token_key, token_secret=token_secret) self.url = 'http://www.theatlantic.com/technology/archive/2013/01/the-never-before-told-story-of-the-worlds-first-computer-art-its-a-sexy-dame/267439/' add_response = self.reader_client.add_bookmark(self.url) self.assertTrue(add_response.status_code in [201, 202])
def save_data(self, token, trigger_id, **data): """ let's save the data :param trigger_id: trigger ID from which to save data :param **data: the data to check to be used and save :type trigger_id: int :type **data: dict :return: the status of the save statement :rtype: boolean """ status = False if token and 'link' in data and data['link'] is not None and len( data['link']) > 0: # get the data of this trigger trigger = Readability.objects.get(trigger_id=trigger_id) token_key, token_secret = token.split('#TH#') readability_instance = ReaderClient(self.consumer_key, self.consumer_secret, token_key, token_secret) bookmark_id = readability_instance.add_bookmark(url=data['link']) if trigger.tag is not None and len(trigger.tag) > 0: try: readability_instance.add_tags_to_bookmark( bookmark_id, tags=(trigger.tag.lower())) sentence = str('readability {} created item id {}').format( data['link'], bookmark_id) logger.debug(sentence) status = True except Exception as e: logger.critical(e) status = False else: sentence = "no token or link provided for trigger ID {} " logger.critical(sentence.format(trigger_id)) status = False return status
def setUp(self): """Add a few bookmarks. """ token_pair = xauth(CONSUMER_KEY, CONSUMER_SECRET, USERNAME, PASSWORD) self.token_key = token_pair[0] self.token_secret = token_pair[1] self.base_client = ReaderClient(CONSUMER_KEY, CONSUMER_SECRET, self.token_key, self.token_secret) self.urls = [ 'http://www.theatlantic.com/technology/archive/2013/01/the-never-before-told-story-of-the-worlds-first-computer-art-its-a-sexy-dame/267439/', 'http://www.theatlantic.com/business/archive/2013/01/why-smart-poor-students-dont-apply-to-selective-colleges-and-how-to-fix-it/272490/', ] self.favorite_urls = [ 'http://www.theatlantic.com/sexes/archive/2013/01/the-lonely-existence-of-mel-feit-mens-rights-advocate/267413/', 'http://www.theatlantic.com/technology/archive/2013/01/women-in-combat-an-idea-whose-time-has-come-aided-by-technology/272483/' ] self.archive_urls = [ 'http://www.theatlantic.com/business/archive/2013/01/what-economics-can-and-cant-tell-us-about-the-legacy-of-legal-abortion/267459/', 'http://www.theatlantic.com/business/archive/2013/01/5-ways-to-understand-just-how-absurd-spains-26-unemployment-rate-is/272502/' ] self.all_urls = self.urls + self.favorite_urls + self.archive_urls for url in self.urls: add_response = self.base_client.add_bookmark(url) self.assertEqual(add_response.status, 202) for url in self.favorite_urls: add_response = self.base_client.add_bookmark(url, favorite=True) self.assertEqual(add_response.status, 202) for url in self.archive_urls: add_response = self.base_client.add_bookmark(url, archive=True) self.assertEqual(add_response.status, 202)
def process_data(self, token, trigger_id, date_triggered): """ get the data from the service """ data = [] if token is not None: token_key, token_secret = token.split('#TH#') client = ReaderClient( self.consumer_key, self.consumer_secret, token_key, token_secret) bookmarks = client.get_bookmarks( added_since=date_triggered).content for bookmark in bookmarks.values(): for b in bookmark: if 'article' in b: title = '' if 'title' in b['article']: title = b['article']['title'] link = '' if 'url' in b['article']: link = b['article']['url'] content = '' if 'excerpt' in b['article']: content = b['article']['excerpt'] data.append( {'title': title, 'link': link, 'content': content}) return data
def __init__(self, token=None, **kwargs): super(ServiceReadability, self).__init__(token, **kwargs) base = 'https://www.readability.com' self.AUTH_URL = '{}/api/rest/v1/oauth/authorize/'.format(base) self.REQ_TOKEN = '{}/api/rest/v1/oauth/request_token/'.format(base) self.ACC_TOKEN = '{}/api/rest/v1/oauth/access_token/'.format(base) self.consumer_key = settings.TH_READABILITY['consumer_key'] self.consumer_secret = settings.TH_READABILITY['consumer_secret'] self.token = token self.service = 'ServiceReadability' self.oauth = 'oauth1' kwargs = {'consumer_key': self.consumer_key, 'consumer_secret': self.consumer_secret} if token: token_key, token_secret = self.token.split('#TH#') self.client = ReaderClient(token_key, token_secret, **kwargs)
class ReaderClientMultipleBookmarkTest(unittest.TestCase): """ Tests for bookmark functionality """ def setUp(self): """ Add a few bookmarks. """ token_key, token_secret = xauth() self.reader_client = ReaderClient(token_key=token_key, token_secret=token_secret) self.urls = [ 'http://www.theatlantic.com/technology/archive/2013/01/the-never-before-told-story-of-the-worlds-first-computer-art-its-a-sexy-dame/267439/', 'http://www.theatlantic.com/business/archive/2013/01/why-smart-poor-students-dont-apply-to-selective-colleges-and-how-to-fix-it/272490/', ] self.favorite_urls = [ 'http://www.theatlantic.com/sexes/archive/2013/01/the-lonely-existence-of-mel-feit-mens-rights-advocate/267413/', 'http://www.theatlantic.com/technology/archive/2013/01/women-in-combat-an-idea-whose-time-has-come-aided-by-technology/272483/' ] self.archive_urls = [ 'http://www.theatlantic.com/business/archive/2013/01/what-economics-can-and-cant-tell-us-about-the-legacy-of-legal-abortion/267459/', 'http://www.theatlantic.com/business/archive/2013/01/5-ways-to-understand-just-how-absurd-spains-26-unemployment-rate-is/272502/' ] self.all_urls = self.urls + self.favorite_urls + self.archive_urls for url in self.urls: response = self.reader_client.add_bookmark(url) self.assertTrue(response.status_code in [201, 202]) for url in self.favorite_urls: response = self.reader_client.add_bookmark(url, favorite=True) self.assertTrue(response.status_code in [201, 202]) for url in self.archive_urls: response = self.reader_client.add_bookmark(url, archive=True) self.assertTrue(response.status_code in [201, 202]) def test_get_bookmarks(self): """ Test getting all bookmarks """ response = self.reader_client.get_bookmarks() self.assertEqual(response.status_code, 200) self.assertEqual( len(response.json()['bookmarks']), len(self.all_urls)) # test favorite bookmarks response = self.reader_client.get_bookmarks(favorite=True) self.assertEqual(response.status_code, 200) self.assertEqual( len(response.json()['bookmarks']), len(self.favorite_urls)) for bm in response.json()['bookmarks']: self.assertTrue(bm['article']['url'] in self.favorite_urls) # test archive bookmarks response = self.reader_client.get_bookmarks(archive=True) self.assertEqual(response.status_code, 200) self.assertEqual( len(response.json()['bookmarks']), len(self.archive_urls)) for bm in response.json()['bookmarks']: self.assertTrue(bm['article']['url'] in self.archive_urls) def tearDown(self): """ Remove all added bookmarks. """ for bm in self.reader_client.get_bookmarks().json()['bookmarks']: del_response = self.reader_client.delete_bookmark(bm['id']) self.assertEqual(del_response.status_code, 204)
class ReaderClientSingleBookmarkTest(unittest.TestCase): """ Tests that only need one bookmark """ def setUp(self): """ Get a client and add a bookmark """ token_key, token_secret = xauth() self.reader_client = ReaderClient(token_key=token_key, token_secret=token_secret) self.url = 'http://www.theatlantic.com/technology/archive/2013/01/the-never-before-told-story-of-the-worlds-first-computer-art-its-a-sexy-dame/267439/' add_response = self.reader_client.add_bookmark(self.url) self.assertTrue(add_response.status_code in [201, 202]) def tearDown(self): """ Remove all added bookmarks. """ for bm in self.reader_client.get_bookmarks().json()['bookmarks']: del_response = self.reader_client.delete_bookmark(bm['id']) self.assertEqual(del_response.status_code, 204) def test_get_bookmark(self): """ Test getting one bookmark by id """ bookmark_id = self._get_bookmark_data()['id'] bm_response = self.reader_client.get_bookmark(bookmark_id) self.assertEqual(bm_response.status_code, 200) some_expected_keys = set(['article', 'user_id', 'favorite', 'id']) received_keys = set(bm_response.json().keys()) self.assertTrue(some_expected_keys.issubset(received_keys)) def test_bookmark_tag_functionality(self): """ Test adding, fetching and deleting tags on a bookmark. """ bookmark_id = self._get_bookmark_data()['id'] # test getting empty tags tag_response = self.reader_client.get_bookmark_tags(bookmark_id) self.assertEqual(tag_response.status_code, 200) self.assertEqual(len(tag_response.json()['tags']), 0) # test adding tags tags = ['tag', 'another tag'] tag_string = ', '.join(tags) tag_add_response = \ self.reader_client.add_tags_to_bookmark(bookmark_id, tag_string) self.assertEqual(tag_add_response.status_code, 202) # re-fetch tags. should have 2 retag_response = self.reader_client.get_bookmark_tags(bookmark_id) self.assertEqual(retag_response.status_code, 200) self.assertEqual(len(retag_response.json()['tags']), 2) for tag in retag_response.json()['tags']: self.assertTrue(tag['text'] in tags) # test getting tags for user user_tag_resp = self.reader_client.get_tags() self.assertEqual(user_tag_resp.status_code, 200) self.assertEqual(len(user_tag_resp.json()['tags']), 2) for tag in user_tag_resp.json()['tags']: self.assertTrue(tag['text'] in tags) # test getting a single tag while we're here single_tag_resp = self.reader_client.get_tag(tag['id']) self.assertEqual(single_tag_resp.status_code, 200) self.assertTrue('applied_count' in single_tag_resp.json()) self.assertTrue('id' in single_tag_resp.json()) self.assertTrue('text' in single_tag_resp.json()) # delete tags for tag in retag_response.json()['tags']: del_response = self.reader_client.delete_tag_from_bookmark( bookmark_id, tag['id']) self.assertEqual(del_response.status_code, 204) # check that tags are gone tag_response = self.reader_client.get_bookmark_tags(bookmark_id) self.assertEqual(tag_response.status_code, 200) self.assertEqual(len(tag_response.json()['tags']), 0) def _get_bookmark_data(self): """ Convenience method to get a single bookmark's data. """ bm_response = self.reader_client.get_bookmarks() self.assertEqual(bm_response.status_code, 200) bm_response_json = bm_response.json() self.assertTrue(len(bm_response_json['bookmarks']) > 0) return bm_response_json['bookmarks'][0]
"since": since, "sort": "oldest", "count": 20 }) articles = res.json()['list'] if not articles: since = res.json()['since'] with open('metadata.json', 'w') as f: f.write(json.dumps({"since": since})) exit(0) articles = sorted(articles.values(), key=lambda x: x['sort_id']) # sort_id is provided by pocket to denote sort order since = str(int(articles[-1]['time_updated']) + 1) with open('metadata.json', 'w') as f: f.write(json.dumps({"since": since})) readability = ReaderClient( token_key=config.READABILITY_USER_KEY, token_secret=config.READABILITY_USER_SECRET, consumer_key=config.READABILITY_CONSUMER_KEY, consumer_secret=config.READABILITY_CONSUMER_SECRET ) for a in articles: readability.add_bookmark(a['resolved_url'])
class ReaderClientSingleBookmarkTest(TestCase): """Tests that only need one bookmark """ def setUp(self): """Get a client and add a bookmark """ token_pair = xauth(CONSUMER_KEY, CONSUMER_SECRET, USERNAME, PASSWORD) self.token_key = token_pair[0] self.token_secret = token_pair[1] self.base_client = ReaderClient(CONSUMER_KEY, CONSUMER_SECRET, self.token_key, self.token_secret) self.url = 'http://www.theatlantic.com/technology/archive/2013/01/the-never-before-told-story-of-the-worlds-first-computer-art-its-a-sexy-dame/267439/' add_response = self.base_client.add_bookmark(self.url) self.assertEqual(add_response.status, 202) def tearDown(self): """Remove all added bookmarks. """ for bm in self.base_client.get_bookmarks().content['bookmarks']: del_response = self.base_client.delete_bookmark(bm['id']) self.assertEqual(del_response.status, 204) def test_get_bookmark(self): """Test getting one bookmark by id """ # get a bookmark id bm_response = self.base_client.get_bookmarks() self.assertEqual(bm_response.status, 200) self.assertTrue(len(bm_response.content['bookmarks']) > 0) bookmark_id = bm_response.content['bookmarks'][0]['id'] bm_response = self.base_client.get_bookmark(bookmark_id) self.assertEqual(bm_response.status, 200) some_expected_keys = set(['article', 'user_id', 'favorite', 'id']) received_keys = set(bm_response.content.keys()) self.assertTrue(some_expected_keys.issubset(received_keys)) def test_bookmark_tag_functionality(self): """Test adding, fetching and deleting tags on a bookmark. """ # get a bookmark id bm_response = self.base_client.get_bookmarks() self.assertEqual(bm_response.status, 200) self.assertTrue(len(bm_response.content['bookmarks']) > 0) bookmark_id = bm_response.content['bookmarks'][0]['id'] # test getting empty tags tag_response = self.base_client.get_bookmark_tags(bookmark_id) self.assertEqual(tag_response.status, 200) self.assertEqual(len(tag_response.content['tags']), 0) # test adding tags tags = ['tag', 'another tag'] tag_string = ', '.join(tags) tag_add_response = \ self.base_client.add_tags_to_bookmark(bookmark_id, tag_string) self.assertEqual(tag_add_response.status, 202) # re-fetch tags. should have 2 retag_response = self.base_client.get_bookmark_tags(bookmark_id) self.assertEqual(retag_response.status, 200) self.assertEqual(len(retag_response.content['tags']), 2) for tag in retag_response.content['tags']: self.assertTrue(tag['text'] in tags) # test getting tags for user user_tag_resp = self.base_client.get_tags() self.assertEqual(user_tag_resp.status, 200) self.assertEqual(len(user_tag_resp.content['tags']), 2) for tag in user_tag_resp.content['tags']: self.assertTrue(tag['text'] in tags) # test getting a single tag while we're here single_tag_resp = self.base_client.get_tag(tag['id']) self.assertEqual(single_tag_resp.status, 200) self.assertTrue('applied_count' in single_tag_resp.content) self.assertTrue('id' in single_tag_resp.content) self.assertTrue('text' in single_tag_resp.content) # delete tags for tag in retag_response.content['tags']: del_response = self.base_client.delete_tag_from_bookmark( bookmark_id, tag['id']) self.assertEqual(del_response.status, 204) # check that tags are gone tag_response = self.base_client.get_bookmark_tags(bookmark_id) self.assertEqual(tag_response.status, 200) self.assertEqual(len(tag_response.content['tags']), 0)
class ReaderClientMultipleBookmarkTest(TestCase): """Tests for bookmark functionality """ def setUp(self): """Add a few bookmarks. """ token_pair = xauth(CONSUMER_KEY, CONSUMER_SECRET, USERNAME, PASSWORD) self.token_key = token_pair[0] self.token_secret = token_pair[1] self.base_client = ReaderClient(CONSUMER_KEY, CONSUMER_SECRET, self.token_key, self.token_secret) self.urls = [ 'http://www.theatlantic.com/technology/archive/2013/01/the-never-before-told-story-of-the-worlds-first-computer-art-its-a-sexy-dame/267439/', 'http://www.theatlantic.com/business/archive/2013/01/why-smart-poor-students-dont-apply-to-selective-colleges-and-how-to-fix-it/272490/', ] self.favorite_urls = [ 'http://www.theatlantic.com/sexes/archive/2013/01/the-lonely-existence-of-mel-feit-mens-rights-advocate/267413/', 'http://www.theatlantic.com/technology/archive/2013/01/women-in-combat-an-idea-whose-time-has-come-aided-by-technology/272483/' ] self.archive_urls = [ 'http://www.theatlantic.com/business/archive/2013/01/what-economics-can-and-cant-tell-us-about-the-legacy-of-legal-abortion/267459/', 'http://www.theatlantic.com/business/archive/2013/01/5-ways-to-understand-just-how-absurd-spains-26-unemployment-rate-is/272502/' ] self.all_urls = self.urls + self.favorite_urls + self.archive_urls for url in self.urls: add_response = self.base_client.add_bookmark(url) self.assertEqual(add_response.status, 202) for url in self.favorite_urls: add_response = self.base_client.add_bookmark(url, favorite=True) self.assertEqual(add_response.status, 202) for url in self.archive_urls: add_response = self.base_client.add_bookmark(url, archive=True) self.assertEqual(add_response.status, 202) def test_get_bookmarks(self): """Test getting all bookmarks """ bm_response = self.base_client.get_bookmarks() self.assertEqual(bm_response.status, 200) self.assertEqual(len(bm_response.content['bookmarks']), len(self.all_urls)) # test favorite bookmarks bm_response = self.base_client.get_bookmarks(favorite=True) self.assertEqual(bm_response.status, 200) self.assertEqual(len(bm_response.content['bookmarks']), len(self.favorite_urls)) for bm in bm_response.content['bookmarks']: self.assertTrue(bm['article']['url'] in self.favorite_urls) # test archive bookmarks bm_response = self.base_client.get_bookmarks(archive=True) self.assertEqual(bm_response.status, 200) self.assertEqual(len(bm_response.content['bookmarks']), len(self.archive_urls)) for bm in bm_response.content['bookmarks']: self.assertTrue(bm['article']['url'] in self.archive_urls) def tearDown(self): """Remove all added bookmarks. """ for bm in self.base_client.get_bookmarks().content['bookmarks']: del_response = self.base_client.delete_bookmark(bm['id']) self.assertEqual(del_response.status, 204)
def readability_exporter(api_key, api_secret, login_user, login_pw, format, bookmarks, export_directory, export_filename, not_show_file, http_error_threshold): """Readability Exporter This little script takes credentials for a Readability account and the API key and secret to create the standard Readability export file in JSON format that can be used to import your links into Instapaper. We think about adding support for the del.icio.us flavour of bookmarks.html to allow direct import into Pocket. You can find more information about this script on GitHub at https://github.com/goetzb/readability-exporter """ click.echo(click.style('Readability Exporter', bold=True)) # Create string for export filename if '{timestamp}' not in export_filename: export_filename += '_{timestamp}' if '{format}' not in export_filename: export_filename += '_{format}' if '{filetype}' not in export_filename: export_filename += '.{filetype}' # Prepare json export dictionary export_dict = OrderedDict() export_dict['bookmarks'] = [] # Add empty recommendations list - in my example this was just empty. export_dict["recommendations"] = [] # Prepare jsonraw export dictionary export_dict_raw = OrderedDict() # Prepare html export string export_html = """<!DOCTYPE NETSCAPE-Bookmark-file-1> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"> <!-- This is an automatically generated file. It will be read and overwritten. Do Not Edit! --> <TITLE>Bookmarks</TITLE> <H1>Bookmarks</H1> <DL><p> """ auth_tokens = get_auth_tokens(api_key=api_key, api_secret=api_secret, login_user=login_user, login_pw=login_pw) if len(auth_tokens) != 2: click.ClickException( """An error occurred and you could not be authenticated successfully. Please check your Readability API keys and login details.""") client = ReaderClient(token_key=auth_tokens[0], token_secret=auth_tokens[1], consumer_key=api_key, consumer_secret=api_secret) meta_infos = get_readability_meta_infos(readability_reader_client=client) click.echo("* You have saved " + click.style("{link_count}".format( link_count=meta_infos['bookmarks_total']), bold=True) + " links on Readability") if bookmarks == 0: bookmarks = meta_infos['bookmarks_total'] click.echo("* We are now going to export the latest " + click.style("{export_count}".format(export_count=bookmarks), bold=True) + " of your links") if bookmarks < 50: bookmarks_per_page = bookmarks + 1 else: bookmarks_per_page = 50 bookmarks_get_pages = int(ceil(bookmarks / bookmarks_per_page)) data_export = export_bookmarks_via_api( readability_reader_client=client, export_formats=format, bookmarks_number=bookmarks, bookmarks_per_page=bookmarks_per_page, bookmarks_get_pages=bookmarks_get_pages, export_json=export_dict, export_html=export_html, export_jsonraw=export_dict_raw, error_threshold=http_error_threshold) click.echo( "Bear with us, we are almost there. In the next step we bring the data into the right formats." ) exported_files = [] files_export_count = 0 timestamp = datetime.now().strftime("%Y-%m-%d_%H%M%S") with click.progressbar(label='Writing export files...', length=len(format), show_percent=True) as files_bar: for export_format in format: output_data = data_export[export_format] if export_format == 'json' or export_format == 'jsonraw': filetype = 'json' elif export_format == 'html': filetype = 'html' output_data += "</DL><p>" format_export_filename = export_filename.format( timestamp=timestamp, format=export_format, filetype=filetype) export_file = write_export_data(filetype=filetype, directory=export_directory, filename=format_export_filename, data=output_data) exported_files.append(export_file) files_export_count += 1 files_bar.update(files_export_count) # TODO: Improve bookmark count to verify if actually the correct number of bookmarks has been exported # Get length of 'bookmarks' in json export dictionary click.echo( click.style( "Good news! We have successfully exported {number_of_bookmarks} bookmarks for you." .format(number_of_bookmarks=bookmarks), fg='green')) for exported_file in exported_files: if exported_file['file_size'] / 1024 > 1024: file_size_string = '{size:d} MiB'.format( size=int(round(exported_file['file_size'] / 1024 / 1024))) elif exported_file['file_size'] > 1024: file_size_string = '{size:d} KiB'.format( size=int(round(exported_file['file_size'] / 1024))) else: file_size_string = '{size:d} B'.format( size=exported_file['file_size']) click.echo("You can find your exported data in ") click.echo( click.style(" {path}".format(path=exported_file['file_path']), bold=True)) click.echo(" (~{size})".format(size=file_size_string)) click.echo( click.style("Thank you for using this little tool!", reverse=True)) if not not_show_file: click.echo( click.style( "We will now try to open your file manager with the exported file selected.", reverse=True)) click.launch(export_directory, locate=True)
class ReaderClientNoBookmarkTest(TestCase): """Tests for the Readability ReaderClient class that need no bookmarks. """ def setUp(self): """Need to get a token for each test. """ token_pair = xauth(CONSUMER_KEY, CONSUMER_SECRET, USERNAME, PASSWORD) self.token_key = token_pair[0] self.token_secret = token_pair[1] self.base_client = ReaderClient(CONSUMER_KEY, CONSUMER_SECRET, self.token_key, self.token_secret) def test_get_article(self): """Test the `get_article` method. """ article_id = 'lun3elns' response = self.base_client.get_article(article_id) self.assertEqual(response.status, 200) self.assertTrue(isinstance(response.content, dict)) # spot check some keys some_expected_keys = set([ 'direction', 'title', 'url', 'excerpt', 'content', 'processed', 'short_url', 'date_published' ]) keys_set = set(response.content.keys()) self.assertTrue(some_expected_keys.issubset(keys_set)) def test_get_article_404(self): """Try getting an article that doesn't exist. """ article_id = 1 response = self.base_client.get_article(article_id) self.assertEqual(response.status, 404) self.assertTrue(isinstance(response.content, dict)) self.assertTrue('error_message' in response.content) def test_get_user(self): """Test getting user data """ user_response = self.base_client.get_user() self.assertEqual(user_response.status, 200) some_expected_keys = set([ 'username', 'first_name', 'last_name', 'date_joined', 'email_into_address' ]) received_keys = set(user_response.content.keys()) self.assertTrue(some_expected_keys.issubset(received_keys)) def _test_get_tags(self): """Test getting tags. """ tag_response = self.base_client.get_tags() self.assertEqual(tag_response.status, 200) self.assertTrue('tags' in tag_response.content) self.assertTrue(len(tag_response.content['tags']) > 0)
class ServiceReadability(ServicesMgr): def __init__(self, token=None): base = 'https://www.readability.com' self.AUTH_URL = '{}/api/rest/v1/oauth/authorize/'.format(base) self.REQ_TOKEN = '{}/api/rest/v1/oauth/request_token/'.format(base) self.ACC_TOKEN = '{}/api/rest/v1/oauth/access_token/'.format(base) self.consumer_key = settings.TH_READABILITY['consumer_key'] self.consumer_secret = settings.TH_READABILITY['consumer_secret'] if token: token_key, token_secret = token.split('#TH#') self.client = ReaderClient(token_key, token_secret, self.consumer_key, self.consumer_secret) def read_data(self, token, trigger_id, date_triggered): """ get the data from the service :param trigger_id: trigger ID to process :param date_triggered: the date of the last trigger :type trigger_id: int :type date_triggered: datetime :return: list of data found from the date_triggered filter :rtype: list """ data = [] if token is not None: bookmarks = self.client.get_bookmarks( added_since=date_triggered).content for bookmark in bookmarks.values(): for b in bookmark: if 'article' in b: title = '' if 'title' in b['article']: title = b['article']['title'] link = '' if 'url' in b['article']: link = b['article']['url'] content = '' if 'excerpt' in b['article']: content = b['article']['excerpt'] data.append( {'title': title, 'link': link, 'content': content}) cache.set('th_readability_' + str(trigger_id), data) return data def process_data(self, trigger_id): """ get the data from the cache :param trigger_id: trigger ID from which to save data :type trigger_id: int """ cache_data = cache.get('th_readability_' + str(trigger_id)) return PublishingLimit.get_data('th_readability_', cache_data, trigger_id) def save_data(self, token, trigger_id, **data): """ let's save the data :param trigger_id: trigger ID from which to save data :param **data: the data to check to be used and save :type trigger_id: int :type **data: dict :return: the status of the save statement :rtype: boolean """ status = False if token and 'link' in data and\ data['link'] is not None and\ len(data['link']) > 0: # get the data of this trigger trigger = Readability.objects.get(trigger_id=trigger_id) bookmark_id = self.client.add_bookmark(url=data['link']) if trigger.tag is not None and len(trigger.tag) > 0: try: self.client.add_tags_to_bookmark( bookmark_id, tags=(trigger.tag.lower())) sentence = str('readability {} created item id {}').format( data['link'], bookmark_id) logger.debug(sentence) status = True except Exception as e: logger.critical(e) status = False else: sentence = "no token or link provided for trigger ID {} " logger.critical(sentence.format(trigger_id)) status = False return status def auth(self, request): """ let's auth the user to the Service """ callback_url = 'http://%s%s' % ( request.get_host(), reverse('readability_callback')) request_token = self.get_request_token() # Save the request token information for later request.session['oauth_token'] = request_token['oauth_token'] request.session['oauth_token_secret'] = request_token[ 'oauth_token_secret'] # URL to redirect user to, to authorize your app auth_url_str = '%s?oauth_token=%s&oauth_callback=%s' auth_url = auth_url_str % (self.AUTH_URL, request_token['oauth_token'], callback_url) return auth_url def callback(self, request): """ Called from the Service when the user accept to activate it """ try: # finally we save the user auth token # As we already stored the object ServicesActivated # from the UserServiceCreateView now we update the same # object to the database so : # 1) we get the previous objet us = UserService.objects.get( user=request.user, name=ServicesActivated.objects.get(name='ServiceReadability')) # 2) Readability API require to use 4 parms consumer_key/secret + # token_key/secret instead of usually get just the token # from an access_token request. So we need to add a string # seperator for later use to slpit on this one access_token = self.get_access_token( request.session['oauth_token'], request.session['oauth_token_secret'], request.GET.get('oauth_verifier', '') ) us.token = access_token.get('oauth_token') + \ '#TH#' + access_token.get('oauth_token_secret') # 3) and save everything us.save() except KeyError: return '/' return 'readability/callback.html' def get_request_token(self): oauth = OAuth1Session(self.consumer_key, client_secret=self.consumer_secret) return oauth.fetch_request_token(self.REQ_TOKEN) def get_access_token(self, oauth_token, oauth_token_secret, oauth_verifier): # Using OAuth1Session oauth = OAuth1Session(self.consumer_key, client_secret=self.consumer_secret, resource_owner_key=oauth_token, resource_owner_secret=oauth_token_secret, verifier=oauth_verifier) oauth_tokens = oauth.fetch_access_token(self.ACC_TOKEN) return oauth_tokens
class ServiceReadability(ServicesMgr): def __init__(self, token=None): base = 'https://www.readability.com' self.AUTH_URL = '{}/api/rest/v1/oauth/authorize/'.format(base) self.REQ_TOKEN = '{}/api/rest/v1/oauth/request_token/'.format(base) self.ACC_TOKEN = '{}/api/rest/v1/oauth/access_token/'.format(base) self.consumer_key = settings.TH_READABILITY['consumer_key'] self.consumer_secret = settings.TH_READABILITY['consumer_secret'] self.token = token if token: token_key, token_secret = self.token.split('#TH#') self.client = ReaderClient(token_key, token_secret, self.consumer_key, self.consumer_secret) def read_data(self, **kwargs): """ get the data from the service :param kwargs: contain keyword args : trigger_id at least :type kwargs: dict :rtype: list """ date_triggered = kwargs['date_triggered'] trigger_id = kwargs['trigger_id'] data = [] if self.token is not None: bookmarks = self.client.get_bookmarks( added_since=date_triggered).content for bookmark in bookmarks.values(): for b in bookmark: if 'article' in b: title = '' if 'title' in b['article']: title = b['article']['title'] link = '' if 'url' in b['article']: link = b['article']['url'] content = '' if 'excerpt' in b['article']: content = b['article']['excerpt'] data.append({ 'title': title, 'link': link, 'content': content }) cache.set('th_readability_' + str(trigger_id), data) return data def process_data(self, **kwargs): """ get the data from the cache :param kwargs: contain keyword args : trigger_id at least :type kwargs: dict """ kw = { 'cache_stack': 'th_readability', 'trigger_id': str(kwargs['trigger_id']) } return super(ServiceReadability, self).process_data(**kw) def save_data(self, trigger_id, **data): """ let's save the data :param trigger_id: trigger ID from which to save data :param data: the data to check to be used and save :type trigger_id: int :type data: dict :return: the status of the save statement :rtype: boolean """ status = False if self.token and 'link' in data and\ data['link'] is not None and\ len(data['link']) > 0: # get the data of this trigger trigger = Readability.objects.get(trigger_id=trigger_id) bookmark_id = self.client.add_bookmark(url=data['link']) if trigger.tag is not None and len(trigger.tag) > 0: try: self.client.add_tags_to_bookmark( bookmark_id, tags=(trigger.tag.lower())) sentence = str('readability {} created item id {}').format( data['link'], bookmark_id) logger.debug(sentence) status = True except Exception as e: logger.critical(e) status = False else: sentence = "no token or link provided for trigger ID {} " logger.critical(sentence.format(trigger_id)) status = False return status def auth(self, request): """ let's auth the user to the Service """ request_token = super(ServiceReadability, self).auth(request) callback_url = self.callback_url(request, 'readability') # URL to redirect user to, to authorize your app auth_url_str = '%s?oauth_token=%s&oauth_callback=%s' auth_url = auth_url_str % (self.AUTH_URL, request_token['oauth_token'], callback_url) return auth_url def callback(self, request): """ Called from the Service when the user accept to activate it """ kwargs = { 'access_token': '', 'service': 'ServiceReadability', 'return': 'readability' } return super(ServiceReadability, self).callback(request, **kwargs)
class ServiceReadability(ServicesMgr): def __init__(self, token=None): base = 'https://www.readability.com' self.AUTH_URL = '{}/api/rest/v1/oauth/authorize/'.format(base) self.REQ_TOKEN = '{}/api/rest/v1/oauth/request_token/'.format(base) self.ACC_TOKEN = '{}/api/rest/v1/oauth/access_token/'.format(base) self.consumer_key = settings.TH_READABILITY['consumer_key'] self.consumer_secret = settings.TH_READABILITY['consumer_secret'] self.token = token if token: token_key, token_secret = self.token.split('#TH#') self.client = ReaderClient(token_key, token_secret, self.consumer_key, self.consumer_secret) def read_data(self, **kwargs): """ get the data from the service :param kwargs: contain keyword args : trigger_id at least :type kwargs: dict :rtype: list """ date_triggered = kwargs['date_triggered'] trigger_id = kwargs['trigger_id'] data = [] if self.token is not None: bookmarks = self.client.get_bookmarks( added_since=date_triggered).content for bookmark in bookmarks.values(): for b in bookmark: if 'article' in b: title = '' if 'title' in b['article']: title = b['article']['title'] link = '' if 'url' in b['article']: link = b['article']['url'] content = '' if 'excerpt' in b['article']: content = b['article']['excerpt'] data.append( {'title': title, 'link': link, 'content': content}) cache.set('th_readability_' + str(trigger_id), data) return data def process_data(self, **kwargs): """ get the data from the cache :param kwargs: contain keyword args : trigger_id at least :type kwargs: dict """ kw = {'cache_stack': 'th_readability', 'trigger_id': str(kwargs['trigger_id'])} return super(ServiceReadability, self).process_data(**kw) def save_data(self, trigger_id, **data): """ let's save the data :param trigger_id: trigger ID from which to save data :param data: the data to check to be used and save :type trigger_id: int :type data: dict :return: the status of the save statement :rtype: boolean """ status = False if self.token and 'link' in data and\ data['link'] is not None and\ len(data['link']) > 0: # get the data of this trigger trigger = Readability.objects.get(trigger_id=trigger_id) bookmark_id = self.client.add_bookmark(url=data['link']) if trigger.tag is not None and len(trigger.tag) > 0: try: self.client.add_tags_to_bookmark( bookmark_id, tags=(trigger.tag.lower())) sentence = str('readability {} created item id {}').format( data['link'], bookmark_id) logger.debug(sentence) status = True except Exception as e: logger.critical(e) status = False else: sentence = "no token or link provided for trigger ID {} " logger.critical(sentence.format(trigger_id)) status = False return status def auth(self, request): """ let's auth the user to the Service """ request_token = super(ServiceReadability, self).auth(request) callback_url = self.callback_url(request, 'readability') # URL to redirect user to, to authorize your app auth_url_str = '%s?oauth_token=%s&oauth_callback=%s' auth_url = auth_url_str % (self.AUTH_URL, request_token['oauth_token'], callback_url) return auth_url def callback(self, request): """ Called from the Service when the user accept to activate it """ kwargs = {'access_token': '', 'service': 'ServiceReadability', 'return': 'readability'} return super(ServiceReadability, self).callback(request, **kwargs)