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 setClient(self, channel): logging.info(" Connecting Medium") logging.info(f" Connecting Medium {channel}") self.service = 'Medium' client = None userRaw = None user = None try: config = configparser.ConfigParser() config.read(CONFIGDIR + '/.rssMedium') application_id = config.get("appKeys", "ClientID") application_secret = config.get("appKeys", "ClientSecret") try: client = Client(application_id=application_id, application_secret=application_secret) try: client.access_token = config.get(channel, "access_token") except: client.access_token = config.get("appKeys", "access_token") # client.access_token = config.get("appKeys","access_token") # Get profile details of the user identified by the access # token. userRaw = client.get_current_user() user = userRaw['username'] except: logging.warning("Medium authentication failed!") logging.warning("Unexpected error:", sys.exc_info()) except: logging.warning("Account not configured") self.client = client self.user = user self.userRaw = userRaw
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 connectMedium(): config = configparser.ConfigParser() config.read([os.path.expanduser('~/.rssMedium')]) client = Client(application_id=config.get("appKeys", "ClientID"), application_secret=config.get("appKeys", "ClientSecret")) try: client.access_token = config.get("appKeys", "access_token") # Get profile details of the user identified by the access token. user = client.get_current_user() except: print("Medium authentication failed!\n") print("Unexpected error:", sys.exc_info()[0]) return (client, user)
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 medium_callback(): if request.args.get('code'): client = Client( application_id="888a966258eb", application_secret="00769027e3d5b60bef015e4924a2bc3022218de9") auth_code = request.args.get('code') auth = client.exchange_authorization_code( auth_code, "http://0094f685.ngrok.io/api/callback/medium") client.access_token = auth["access_token"] user = client.get_current_user() user_dir = 'users/' + user["username"] if not os.path.exists(user_dir): os.makedirs(user_dir) with open(user_dir + '/token.json', 'w+') as f: json.dump(auth, f) f.close() with open(user_dir + '/user.json', 'w+') as f: json.dump(user, f) f.close() with open('users.txt', 'a+') as f: f.write('{}\n'.format(user["username"])) f.close()
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']))
print( "Authorization code (at the end of the url that was just opened):") authorization_code = sys.stdin.readline().strip() # Exchange the authorization code for an access token. auth = client.exchange_authorization_code(authorization_code, callback_url) # The access token is automatically set on the client for you after # a successful exchange, but if you already have a token, you can set it # directly. client.access_token = auth["access_token"] # Get profile details of the user identified by the access token. user = client.get_current_user() print(user) # Get publications publications = client._request( "GET", "/v1/users/" + user["id"] + "/publications") print(publications) # # Create a draft post. # post = client.create_post(user_id=user["id"], title="Title", content="<h2>Title</h2><p>Content</p>", # content_format="html", publish_status="draft") # # When your access token expires, use the refresh token to get a new one. # client.exchange_refresh_token(auth["refresh_token"]) # # Confirm everything went ok. post["url"] has the location of the created post.
def call_back(): global refresh_button_click global total_posts global count_length global user_profile global user_image global user_type global pub_name global desrip_pub global image_pub global url_pub global rss_link if (refresh_button_click == True): #authentication process to get the acess token # Exchange the authorization code for an access token. client = Client(application_id=medium_app_id, application_secret=medium_app_secret) #get_pub = Client(application_id="45ec1ddf13cb", application_secret="b42623c0f2ee207a6872a76c0bc7c2eb88411a77") secret = request.args.get("code") auth = client.exchange_authorization_code( secret, "{}/resultDisplay/callback/medium".format(ngrok_link)) client.access_token = auth["access_token"] # Get profile details of the user identified by the access token. user = client.get_current_user() user_profile = user["username"] user_image = user["imageUrl"] user_id = user["id"] user_type = type(user) token = auth["access_token"] publications = get_current_publications(user_id, token) json_data_type = json.loads(publications.text) #publications.json() data_list = json_data_type["data"] #capture the data in the database.... database.insert_data(user_profile, user, data_list, datetime.now()) # To determined the length of the publication.. count_length = len(data_list) #testing #rss_links1=rss_feed[1].get("link") get_publications_data(data_list) ''' for dict_item in data_list: for key,value in dict_item.items(): if key=="id": pass else: if key=="name": pub_name.append(value) if key=="description": desrip_pub.append(value) if key=="imageUrl": image_pub.append(value) if key=="url": url_pub.append(value) ''' #person_data["name"] #get the user feeder data name = str(user["username"]) rss_feed = get_medium(name) #store relevant data from the rss_feed to the rss_list get_medium_rss_data(rss_feed) #get the total posts of the user total_posts = len(rss_feed) #set refresh button click to false. refresh_button_click = False return render_template('callback.html', total_posts=total_posts, count_length=count_length, user_profile=user_profile, user_image=user_image, user_type=user_type, pub_name=pub_name, desrip_pub=desrip_pub, image_pub=image_pub, url_pub=url_pub, rss_links=rss_links, rss_tags=rss_tags, rss_titles=rss_titles) else: if (database.is_greater_than_cach_time(datetime.now())): #get datas from the database new_data = database.retrive_data() #insert it back to the lists.... user_details = new_data[0]['userdetails'] pub_details = new_data[0]['publications'] #assigned it back to list variables for user details and publications details user_profile = user_details['username'] user_image = user_details['imageUrl'] user_id = user_details['id'] user_type = type(user_details) get_publications_data(pub_details) return render_template('callback.html', total_posts=total_posts, count_length=count_length, user_profile=user_profile, user_image=user_image, user_type=user_type, pub_name=pub_name, desrip_pub=desrip_pub, image_pub=image_pub, url_pub=url_pub, rss_links=rss_links, rss_tags=rss_tags, rss_titles=rss_titles) else: return render_template('callback.html', total_posts=total_posts, count_length=count_length, user_profile=user_profile, user_image=user_image, user_type=user_type, pub_name=pub_name, desrip_pub=desrip_pub, image_pub=image_pub, url_pub=url_pub, rss_links=rss_links, rss_tags=rss_tags, rss_titles=rss_titles)
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)