class TestIsaac(unittest.TestCase): def setUp(self): self.client = Client(access_token="isaac-token") @responses.activate def test_create_post_fails(self): """Tests whether MediumError exception occurs if publish_status is not in the payload""" def response_callback(payload): data = { "license": "all-rights-reserved", "title": "Starships", "url": "https://medium.com/@nicki/55050649c95", "tags": ["stars", "ships", "pop"], "authorId": "5303d74c64f66366f00cb9b2a94f3251bf5", "publishStatus": "draft", "id": "55050649c95", } if "publish_status" in payload: return 200, data return 400, {"error": ["Bad Request"]} self._mock_endpoint( "POST", "/v1/users/5303d74c64f66366f00cb9b2a94f3251bf5/posts", response_callback) with self.assertRaises(MediumError) as context: self.client.create_post("5303d74c64f66366f00cb9b2a94f3251bf5", "Starships", "<p>Are meant to flyyyy</p>", "html", tags=["stars", "ships", "pop"]) self.assertEqual('API request failed', str(context.exception)) def _mock_endpoint(self, method, path, callback, is_json=True): def wrapped_callback(req): if is_json: self.assertEqual(req.headers["Authorization"], "Bearer isaac-token") if req.body is not None: body = json.loads(req.body) if is_json else parse_qs(req.body) else: body = None status, data = callback(body) return status, {}, json.dumps(data) response_method = responses.GET if method == "GET" else responses.POST url = "https://api.medium.com" + path content_type = ("application/json" if is_json else "application/x-www-form-urlencoded") responses.add_callback(response_method, url, content_type=content_type, callback=wrapped_callback)
def _execute(self, options, args): """Publish to Medium.""" if not os.path.exists('medium.json'): LOGGER.error( 'Please put your credentials in medium.json as described in the README.' ) return False with open('medium.json') as inf: creds = json.load(inf) client = Client() client.access_token = creds['TOKEN'] user = client.get_current_user() self.site.scan_posts() for post in self.site.timeline: if post.meta('medium'): m_post = client.create_post( user_id=user["id"], title=post.title(), content=post.text(), content_format="html", publish_status="public", canonical_url=post.permalink(absolute=True), tags=post.tags) print('Published %s to %s' % (post.meta('slug'), m_post['url']))
def postToMedium(heading,body): client = Client(application_id = ENV["APP_ID"],application_secret = ENV["APP_SECRET"]) client.access_token = ENV["ACCESS_TOKEN"] user = client.get_current_user() post = client.create_post(user_id = user["id"], title = heading, content = body, content_format = "markdown", publish_status = "draft") print("New!! post at ",post["url"])
def push_to_medium(self): """Prepare final content, upload post to Medium""" self.title = self.meta.get('title', config.DEFAULT_TITLE) if self.include_attribution: self.add_attribution() self.content = ''.join(self.final_lines) client = Client(access_token=secrets.MEDIUM_TOKEN) me = client.get_current_user() self.post = client.create_post(user_id=me['id'], title=self.title, \ content=self.content, content_format="markdown", \ publish_status=config.PUBLISH_STATUS) print(self.post)
def _execute(self, options, args): """Publish to Medium.""" if not os.path.exists("medium.json"): LOGGER.error( "Please put your credentials in medium.json as described in the README." ) return False with open("medium.json") as inf: creds = json.load(inf) client = Client() client.access_token = creds["TOKEN"] user = client.get_current_user() self.site.scan_posts() feed = client.list_articles(user["username"]) posts = self.site.timeline medium_titles = {item["title"] for item in feed} to_post = [ post for post in posts if post.title() not in medium_titles and post.meta("medium") ] if len(to_post) == 0: print("Nothing new to post...") for post in to_post: with open(post.source_path, "r") as file: data = file.read() pattern = "(?m)^# .*\n$" title = "" match = re.search(pattern, data) if not match: title = f"# {post.title()}\n" content = (title + "*Original article : " + post.permalink(absolute=True) + "*\n" + data) else: content = (data[:match.end()] + "\n*Original article : " + post.permalink(absolute=True) + "*\n" + data[match.end():]) m_post = client.create_post( user_id=user["id"], title=post.title(), content=content, content_format="markdown", publish_status="public", canonical_url=post.permalink(absolute=True), tags=post.tags, ) print("Published %s to %s" % (post.meta("slug"), m_post["url"]))
def publish(request): if request.method=="POST": title=request.POST["title"] imgloc=request.POST["img_loc"] content=request.POST["message"] client=Client(application_id="bd2220b27e6a",application_secret="5ea5ccec18e6b7d12466900d47417fdcc52f352f") client.access_token="2a0432ffe8985834d0f939991291b6d589eef0684b425e8fce1c964a7e0be1263" user=client.get_current_user() imgup=client.upload_image(file_path=os.path.join('D:\\IV\\One plus\\Photos',imgloc),content_type="image/jpeg") url=imgup['url'] content="<img src="+url+"><p>"+content+ "</p>" post=client.create_post(user_id=user["id"], title=title,content=content,content_format="html") return render(request,'blank.html',post) else: return render(request,'index.html')
def _execute(self, options, args): """Publish to Medium.""" if not os.path.exists("medium.json"): LOGGER.error( "Please put your credentials in medium.json as described in the README." ) return False with open("medium.json") as inf: creds = json.load(inf) client = Client() client.access_token = creds["TOKEN"] user = client.get_current_user() self.site.scan_posts() feed = client.list_articles(user["username"]) posts = self.site.timeline medium_titles = {item["title"] for item in feed} to_post = [ post for post in posts if post.title() not in medium_titles and post.meta("medium") ] if len(to_post) == 0: print("Nothing new to post...") for post in to_post: tree = html.fromstring(post.text()) toc = tree.xpath('//nav[@id="TOC"]') if len(toc) != 0: toc[0].getparent().remove(toc[0]) if len(tree.xpath("//h1")) == 0: content = "<h1>" + post.title() + "</h1>\n" body = tree.xpath("//div")[0] body.insert(0, etree.XML(content)) m_post = client.create_post( user_id=user["id"], title=post.title(), content=etree.tostring(tree, encoding=str), content_format="html", publish_status="public", canonical_url=post.permalink(absolute=True), tags=post.tags, ) print("Published %s to %s" % (post.meta("slug"), m_post["url"]))
def post_content(medium_content, digest_config=None): "post the Medium content to Medium" medium_client = Client( application_id=digest_config.get("medium_application_client_id"), application_secret=digest_config.get( "medium_application_client_secret"), ) medium_client.access_token = digest_config.get("medium_access_token") medium_user = medium_client.get_current_user() # Set some optional post values publish_status = "draft" medium_license = digest_config.get("medium_license", None) # Create a draft post post = medium_client.create_post( user_id=medium_user["id"], title=utils.formatter_string(medium_content, "title"), content=utils.formatter_string(medium_content, "content"), content_format=utils.formatter_string(medium_content, "contentFormat"), tags=utils.formatter_string(medium_content, "tags"), publish_status=publish_status, license=medium_license, ) return post
def _execute(self, options, args): """Publish to Medium.""" if not os.path.exists('medium.json'): LOGGER.error( 'Please put your credentials in medium.json as described in the README.') return False with open('medium.json') as inf: creds = json.load(inf) client = Client() client.access_token = creds['TOKEN'] user = client.get_current_user() self.site.scan_posts() for post in self.site.timeline: if post.meta('medium'): m_post = client.create_post( user_id=user["id"], title=post.title(), content=post.text(), content_format="html", publish_status="public", canonical_url=post.permalink(absolute=True), tags=post.tags ) print('Published %s to %s' % (post.meta('slug'), m_post['url']))
class TestClient(unittest.TestCase): def setUp(self): self.client = Client(access_token="myaccesstoken") @responses.activate def test_exchange_authorization_code(self): def response_callback(payload): self.assertEqual(payload["code"][0], "mycode") self.assertEqual(payload["client_id"][0], "myclientid") self.assertEqual(payload["client_secret"][0], "myclientsecret") self.assertEqual(payload["grant_type"][0], "authorization_code") self.assertEqual(payload["redirect_uri"][0], "http://example.com/cb") data = { "token_type": "Bearer", "access_token": "myaccesstoken", "expires_at": 4575744000000, "refresh_token": "myrefreshtoken", "scope": ["basicProfile"], } return (201, data) self._mock_endpoint("POST", "/v1/tokens", response_callback, is_json=False) client = Client(application_id="myclientid", application_secret="myclientsecret") # TODO(kyle) Remove after Ceasar's refactoring resp = client.exchange_authorization_code("mycode", "http://example.com/cb") self.assertEqual(resp["access_token"], "myaccesstoken") self.assertEqual(resp["refresh_token"], "myrefreshtoken") self.assertEqual(resp["scope"], ["basicProfile"]) # TODO(kyle) Uncomment after Ceasar's refactoring # client.exchange_authorization_code("mycode", "http://example.com/cb") # self.assertEqual(client.access_token, "myaccesstoken") # self.assertEqual(client.refresh_token, "myrefreshtoken") @responses.activate def test_exchange_refresh_token(self): def response_callback(payload): self.assertEqual(payload["refresh_token"][0], "myrefreshtoken") self.assertEqual(payload["client_id"][0], "myclientid") self.assertEqual(payload["client_secret"][0], "myclientsecret") self.assertEqual(payload["grant_type"][0], "refresh_token") data = { "token_type": "Bearer", "access_token": "myaccesstoken2", "expires_at": 4575744000000, "refresh_token": "myrefreshtoken2", "scope": ["basicProfile"], } return (201, data) self._mock_endpoint("POST", "/v1/tokens", response_callback, is_json=False) client = Client(application_id="myclientid", application_secret="myclientsecret") # TODO(kyle) Remove after Ceasar's refactoring resp = client.exchange_refresh_token("myrefreshtoken") self.assertEqual(resp["access_token"], "myaccesstoken2") self.assertEqual(resp["refresh_token"], "myrefreshtoken2") self.assertEqual(resp["scope"], ["basicProfile"]) # TODO(kyle) Uncomment after Ceasar's refactoring # client.exchange_refresh_token("myrefreshtoken") # self.assertEqual(client.access_token, "myaccesstoken2") # self.assertEqual(client.refresh_token, "myrefreshtoken2") @responses.activate def test_get_current_user(self): def response_callback(payload): data = { "username": "******", "url": "https://medium.com/@nicki", "imageUrl": "https://images.medium.com/0*fkfQiTzT7TlUGGyI.png", "id": "5303d74c64f66366f00cb9b2a94f3251bf5", "name": "Nicki Minaj", } return 200, data self._mock_endpoint("GET", "/v1/me", response_callback) resp = self.client.get_current_user() self.assertEqual(resp, { "username": "******", "url": "https://medium.com/@nicki", "imageUrl": "https://images.medium.com/0*fkfQiTzT7TlUGGyI.png", "id": "5303d74c64f66366f00cb9b2a94f3251bf5", "name": "Nicki Minaj", }) @responses.activate def test_create_post(self): def response_callback(payload): self.assertEqual(payload, { "title": "Starships", "content": "<p>Are meant to flyyyy</p>", "contentFormat": "html", "tags": ["stars", "ships", "pop"], "publishStatus": "draft", }) data = { "license": "all-rights-reserved", "title": "Starships", "url": "https://medium.com/@nicki/55050649c95", "tags": ["stars", "ships", "pop"], "authorId": "5303d74c64f66366f00cb9b2a94f3251bf5", "publishStatus": "draft", "id": "55050649c95", } return 200, data self._mock_endpoint( "POST", "/v1/users/5303d74c64f66366f00cb9b2a94f3251bf5/posts", response_callback ) resp = self.client.create_post( "5303d74c64f66366f00cb9b2a94f3251bf5", "Starships", "<p>Are meant to flyyyy</p>", "html", tags=["stars", "ships", "pop"], publish_status="draft" ) self.assertEqual(resp, { "license": "all-rights-reserved", "title": "Starships", "url": "https://medium.com/@nicki/55050649c95", "tags": ["stars", "ships", "pop"], "authorId": "5303d74c64f66366f00cb9b2a94f3251bf5", "publishStatus": "draft", "id": "55050649c95", }) @responses.activate def test_upload_image(self): def response_callback(req): self.assertEqual(req.headers["Authorization"], "Bearer myaccesstoken") self.assertIn(b"Content-Type: image/png", req.body) return 200, {}, json.dumps({ "url": "https://cdn-images-1.medium.com/0*dlkfjalksdjfl.jpg", "md5": "d87e1628ca597d386e8b3e25de3a18bc", }) responses.add_callback(responses.POST, "https://api.medium.com/v1/images", content_type="application/json", callback=response_callback) resp = self.client.upload_image("./tests/test.png", "image/png") self.assertEqual(resp, { "url": "https://cdn-images-1.medium.com/0*dlkfjalksdjfl.jpg", "md5": "d87e1628ca597d386e8b3e25de3a18bc", }) def _mock_endpoint(self, method, path, callback, is_json=True): def wrapped_callback(req): if is_json: self.assertEqual(req.headers["Authorization"], "Bearer myaccesstoken") if req.body is not None: body = json.loads(req.body) if is_json else parse_qs(req.body) else: body = None status, data = callback(body) return (status, {}, json.dumps(data)) response_method = responses.GET if method == "GET" else responses.POST url = "https://api.medium.com" + path content_type = ("application/json" if is_json else "application/x-www-form-urlencoded") responses.add_callback(response_method, url, content_type=content_type, callback=wrapped_callback)
class TestClient(unittest.TestCase): # TODO: FINISH TESTING CLIENT def setUp(self): self.client = Client(access_token="myaccesstoken") @responses.activate def test_exchange_authorization_code(self): def response_callback(payload): self.assertEqual(payload["code"][0], "mycode") self.assertEqual(payload["client_id"][0], "myclientid") self.assertEqual(payload["client_secret"][0], "myclientsecret") self.assertEqual(payload["grant_type"][0], "authorization_code") self.assertEqual(payload["redirect_uri"][0], "http://example.com/cb") data = { "token_type": "Bearer", "access_token": "myaccesstoken", "expires_at": 4575744000000, "refresh_token": "myrefreshtoken", "scope": ["basicProfile"], } return (201, data) self._mock_endpoint("POST", "/v1/tokens", response_callback, is_json=False) client = Client(application_id="myclientid", application_secret="myclientsecret") @responses.activate def test_exchange_refresh_token(self): def response_callback(payload): self.assertEqual(payload["refresh_token"][0], "myrefreshtoken") self.assertEqual(payload["client_id"][0], "myclientid") self.assertEqual(payload["client_secret"][0], "myclientsecret") self.assertEqual(payload["grant_type"][0], "refresh_token") data = { "token_type": "Bearer", "access_token": "myaccesstoken2", "expires_at": 4575744000000, "refresh_token": "myrefreshtoken2", "scope": ["basicProfile"], } return (201, data) self._mock_endpoint("POST", "/v1/tokens", response_callback, is_json=False) client = Client(application_id="myclientid", application_secret="myclientsecret") @responses.activate def test_get_current_user(self): def response_callback(payload): data = { "username": "******", "url": "https://medium.com/@nicki", "imageUrl": "https://images.medium.com/0*fkfQiTzT7TlUGGyI.png", "id": "5303d74c64f66366f00cb9b2a94f3251bf5", "name": "Nicki Minaj", } return 200, data self._mock_endpoint("GET", "/v1/me", response_callback) resp = self.client.get_current_user() self.assertEqual( resp, { "username": "******", "url": "https://medium.com/@nicki", "imageUrl": "https://images.medium.com/0*fkfQiTzT7TlUGGyI.png", "id": "5303d74c64f66366f00cb9b2a94f3251bf5", "name": "Nicki Minaj", }) @responses.activate def test_create_post(self): def response_callback(payload): self.assertEqual( payload, { "title": "Starships", "content": "<p>Are meant to flyyyy</p>", "contentFormat": "html", "tags": ["stars", "ships", "pop"], "publishStatus": "draft", }) data = { "license": "all-rights-reserved", "title": "Starships", "url": "https://medium.com/@nicki/55050649c95", "tags": ["stars", "ships", "pop"], "authorId": "5303d74c64f66366f00cb9b2a94f3251bf5", "publishStatus": "draft", "id": "55050649c95", } return 200, data self._mock_endpoint( "POST", "/v1/users/5303d74c64f66366f00cb9b2a94f3251bf5/posts", response_callback) resp = self.client.create_post("5303d74c64f66366f00cb9b2a94f3251bf5", "Starships", "<p>Are meant to flyyyy</p>", "html", tags=["stars", "ships", "pop"], publish_status="draft") self.assertEqual( resp, { "license": "all-rights-reserved", "title": "Starships", "url": "https://medium.com/@nicki/55050649c95", "tags": ["stars", "ships", "pop"], "authorId": "5303d74c64f66366f00cb9b2a94f3251bf5", "publishStatus": "draft", "id": "55050649c95", }) @responses.activate def test_upload_image(self): def response_callback(req): self.assertEqual(req.headers["Authorization"], "Bearer myaccesstoken") self.assertIn(b"Content-Type: image/png", req.body) return 200, {}, json.dumps({ "url": "https://cdn-images-1.medium.com/0*dlkfjalksdjfl.jpg", "md5": "d87e1628ca597d386e8b3e25de3a18bc", }) responses.add_callback(responses.POST, "https://api.medium.com/v1/images", content_type="application/json", callback=response_callback) resp = self.client.upload_image("./tests/test.png", "image/png") self.assertEqual( resp, { "url": "https://cdn-images-1.medium.com/0*dlkfjalksdjfl.jpg", "md5": "d87e1628ca597d386e8b3e25de3a18bc", }) def _mock_endpoint(self, method, path, callback, is_json=True): def wrapped_callback(req): if is_json: self.assertEqual(req.headers["Authorization"], "Bearer myaccesstoken") if req.body is not None: body = json.loads(req.body) if is_json else parse_qs(req.body) else: body = None status, data = callback(body) return (status, {}, json.dumps(data)) response_method = responses.GET if method == "GET" else responses.POST url = "https://api.medium.com" + path content_type = ("application/json" if is_json else "application/x-www-form-urlencoded") responses.add_callback(response_method, url, content_type=content_type, callback=wrapped_callback)