diff --git a/crossposter/__init__.py b/crossposter/__init__.py index b019506..21034e3 100644 --- a/crossposter/__init__.py +++ b/crossposter/__init__.py @@ -1 +1 @@ -from app import * +from crossposter import * diff --git a/crossposter/app.py b/crossposter/app.py index 6ad02c4..ff62e5d 100644 --- a/crossposter/app.py +++ b/crossposter/app.py @@ -1,62 +1,85 @@ import sys import frontmatter from pathlib import Path -from publications.dev import devto -from publications.codenewbie import codenewbie -from publications.hashnode import hashnode -from publications.medium import medium +from .publications.dev import devto +from .publications.codenewbie import codenewbie +from .publications.hashnode import hashnode +from .publications.medium import medium import json + def get_default_or_input(dictionary, keys): for key in keys: if key in dictionary.keys(): return dictionary[key] return input(f"Enter the {keys[0]} for post: ") -file_markdown = sys.argv[1] - -post = frontmatter.load(file_markdown) - -with open("config.json", "r") as out: - config = json.load(out) - -output_folder = config["output_folder"] - -output = Path(output_folder) -output.mkdir(parents=True, exist_ok=True) - -blog_link = config["blog_link"] - -article = {} -article["title"] = get_default_or_input(post, ["title"]) -article["description"] = get_default_or_input(post, ["subtitle", "description"]) -slug = get_default_or_input(post, ["slug","canonical_url"]) -if post["slug"]: - slug = blog_link + str(slug) -image_url = get_default_or_input(post, ["image_url", "cover_image"]) - -article["canonical_url"] = slug -article["cover_image"] = image_url -article["tags"] = get_default_or_input(post, ["tags"]) -# article['date']=post['date'] -status = get_default_or_input(post, ["status", "published"]) -if status == "published": - article["published"] = "true" -else: - article["published"] = "false" -article["body_markdown"] = post.content -if "series" in post: - article["series"] = post["series"] - -print(f"1. dev.to \n2. hashnode.com\n3. codenewbie\n4. medium.com\n") -opt = input("Where you would like to post? (1/2/3/4) : ") - -if opt == "1": - devto(article, output) -elif opt == "2": - hashnode(article, output) -elif opt == "3": - codenewbie(article, output) -elif opt == "4": - medium(article, output) -else: - print("Invalid Option") + + +def main(): + file_markdown = sys.argv[1] + + post = frontmatter.load(file_markdown) + + with open("config.json", "r") as out: + config = json.load(out) + + output_folder = config["output_folder"] + + output = Path(output_folder) + output.mkdir(parents=True, exist_ok=True) + + blog_link = config["blog_link"] + + article = {} + article["title"] = get_default_or_input(post, ["title"]) + article["description"] = get_default_or_input(post, ["subtitle", "description"]) + slug = get_default_or_input(post, ["slug", "canonical_url"]) + if post["slug"]: + slug = blog_link + str(slug) + image_url = get_default_or_input(post, ["image_url", "cover_image"]) + + article["canonical_url"] = slug + article["cover_image"] = image_url + article["tags"] = get_default_or_input(post, ["tags"]) + # article['date']=post['date'] + status = get_default_or_input(post, ["status", "published"]) + if status == "published": + article["published"] = "true" + else: + article["published"] = "false" + article["body_markdown"] = post.content + if "series" in post: + article["series"] = post["series"] + + print(f"1. dev.to \n2. hashnode.com\n3. codenewbie\n4. medium.com\n") + opt = input("Where you would like to post? (1/2/3/4) : ") + + key_file = Path("keys.txt") + key_file.touch(exist_ok=True) + if key_file.is_file(): + + f = open(key_file, "r") + lines = f.readlines() + f = open(key_file, "w") + lines.append("dev.to:\n") + lines.append("medium.com:\n") + lines.append("hashnode:\n") + lines.append("hashnode_id:\n") + lines.append("codenewbie:\n") + f.writelines(lines) + f.close() + + if opt == "1": + devto(article, output) + elif opt == "2": + hashnode(article, output) + elif opt == "3": + codenewbie(article, output) + elif opt == "4": + medium(article, output) + else: + print("Invalid Option") + + +if __name__ == "__main__": + main() diff --git a/crossposter/publications/codenewbie.py b/crossposter/publications/codenewbie.py index d793aae..151bbf3 100644 --- a/crossposter/publications/codenewbie.py +++ b/crossposter/publications/codenewbie.py @@ -1,14 +1,21 @@ import requests import json import sys +from crossposter.utils import replace_line + def codenewbie(article, output): - with open("keys.txt", "r") as file: - keys = file.readlines() + for line in open("keys.txt", "r"): + if line.startswith("codenewbie:"): + codenewbie_keys = line.split("codenewbie:")[1] + + if codenewbie_keys != "\n": + codenewbie_keys = codenewbie_keys.strip() + else: + codenewbie_keys = input("Enter the Codenewbie API Key: ") + replace_line("keys.txt", 4, f"dev.to: {codenewbie_keys}\n") - codenewbie_keys = keys[4] - codenewbie_keys = codenewbie_keys.split("codenewbie:")[1].strip() post = {} @@ -34,21 +41,25 @@ def codenewbie(article, output): else: if post[key]: if not key == "published": - codenewbie_frontmatter += f"{key}: \"{post[key]}\"\n" + codenewbie_frontmatter += f'{key}: "{post[key]}"\n' else: codenewbie_frontmatter += f"{key}: {post[key]}\n" - + with open(sys.argv[1], "w") as f: f.write(codenewbie_frontmatter) - filename = post['title'].replace(" ", "_").lower() + filename = post["title"].replace(" ", "_").lower() output_file = output / f"{filename}_codenewbie_post.md" with open(output_file, "w") as file: file.write(codenewbie_frontmatter) flag = True - author_articles_list = json.loads(requests.get("https://community.codenewbie.org/api/articles/me/published", headers=header).content) + author_articles_list = json.loads( + requests.get( + "https://community.codenewbie.org/api/articles/me/published", headers=header + ).content + ) for article_data in author_articles_list: if article["body_markdown"] == article_data["body_markdown"]: flag = False diff --git a/crossposter/publications/dev.py b/crossposter/publications/dev.py index 556acb6..4625c91 100644 --- a/crossposter/publications/dev.py +++ b/crossposter/publications/dev.py @@ -1,12 +1,21 @@ import requests import json import sys +from crossposter.utils import replace_line + def devto(article, output): - with open("keys.txt", "r") as file: - keys = file.readlines() + dev_keys = [] + for line in open("keys.txt", "r"): + if line.startswith("dev.to:"): + dev_keys = line.split("dev.to:")[1] + if dev_keys != "\n": + dev_keys = dev_keys.strip() + else: + dev_keys = input("Enter the DEV API Key: ") + replace_line("keys.txt", 0, f"dev.to: {dev_keys}\n") dev_frontmatter = "---\n" post = {} @@ -17,21 +26,17 @@ def devto(article, output): else: if post[key]: if not key == "published": - dev_frontmatter += f"{key}: \"{post[key]}\"\n" + dev_frontmatter += f'{key}: "{post[key]}"\n' else: dev_frontmatter += f"{key}: {post[key]}\n" - - with open(sys.argv[1], "w") as f: - f.write(dev_frontmatter) - filename = post['title'].replace(" ", "_").lower() + + filename = post["title"].replace(" ", "_").lower() output_file = output / f"{filename}_dev_post.md" with open(output_file, "w") as file: file.write(dev_frontmatter) - - dev_keys = keys[0] dev_keys = dev_keys.split("dev.to:")[1].strip() API_ENDPOINT = "https://dev.to/api/articles" @@ -55,11 +60,13 @@ def devto(article, output): }, } """ - header={"api-key": dev_keys} + header = {"api-key": dev_keys} flag = True - #author_data = json.loads(requests.get("https://dev.to/api/users/me", headers=header).content) - #author_username = author_data["username"] - author_articles_list = json.loads(requests.get("https://dev.to/api/articles/me/published", headers=header).content) + # author_data = json.loads(requests.get("https://dev.to/api/users/me", headers=header).content) + # author_username = author_data["username"] + author_articles_list = json.loads( + requests.get("https://dev.to/api/articles/me/published", headers=header).content + ) for article_data in author_articles_list: if article["body_markdown"] == article_data["body_markdown"]: flag = False diff --git a/crossposter/publications/hashnode.py b/crossposter/publications/hashnode.py index 2cb46b8..2653121 100644 --- a/crossposter/publications/hashnode.py +++ b/crossposter/publications/hashnode.py @@ -7,40 +7,22 @@ def hashnode(article, output): markdown = sys.argv[1] - key_file = Path('keys.txt') - key_file.touch(exist_ok=True) - if key_file.is_file(): + for line in open("keys.txt", "r"): + if line.startswith("hashnode:"): + hashnode_keys = line.split("hashnode:")[1] + if line.startswith("hashnode_id:"): + hashnode_id = line.split("hashnode_id:")[1] - f = open(key_file, "r") - lines = f.readlines() - print(key_file) - f = open(key_file, "w") - lines.append("dev.to:\n") - lines.append("medium.com:\n") - lines.append("hashnode:\n") - lines.append("hashnode_id:\n") - lines.append("codenewbie:\n") - f.writelines(lines) - f.close() - - with open(key_file, "r") as file: - keys = file.readlines() - - if keys: - hashnode_keys = keys[2].split("hashnode:")[1].strip() - hashnode_id = keys[3].split("hashnode_id:")[1].strip() + if hashnode_keys != "\n": + hashnode_keys = hashnode_keys.strip() else: - hashnode_keys = input("Enter the hashnode Keys: ") - hashnode_id = input("Enter your hashnode ID: ") - - f = open(key_file, "r") - lines = f.readlines() - lines[2] = "hashnode:" + hashnode_keys + "\n" - lines[3] = "hashnode_id:" + hashnode_id + "\n" - - f = open(key_file, "w") - f.writelines(lines) - f.close() + hashnode_keys = input("Enter the Hashnode API Key: ") + replace_line("keys.txt", 2, f"hashnode: {hashnode_keys}\n") + if hashnode_id != "\n": + hashnode_id = hashnode_id.strip() + else: + hashnode_id= input("Enter your Hashnode ID: ") + replace_line("keys.txt", 3, f"hashnode_id: {hashnode_id}\n") title = str(article["title"]) subtitle = article["description"] @@ -52,7 +34,7 @@ def hashnode(article, output): "\n", "\\n" ) # .replace("\\c", "\c").replace("\r", "\t") content = "".join(content.splitlines()) - content = str(content.replace("\"", "\'")) + content = str(content.replace('"', "'")) API_ENDPOINT = "https://api.hashnode.com" diff --git a/crossposter/publications/medium.py b/crossposter/publications/medium.py index d978ca5..ece8095 100644 --- a/crossposter/publications/medium.py +++ b/crossposter/publications/medium.py @@ -1,30 +1,29 @@ import requests import json - -def replace_line(file_name, line_num, text): - lines = open(file_name, 'r').readlines() - print(lines) - lines[line_num] = text - out = open(file_name, 'w') - out.writelines(lines) - out.close() +from crossposter.utils import replace_line def medium(article, output): USERNAME_ENDPOINT = "https://api.medium.com/v1/me" - with open('keys.txt', 'r') as f: - keys = f.readlines() - if len(keys[2].split("medium.com"))>1: - medium_token = keys[2].split("medium.com:")[1].strip() + for line in open("keys.txt", "r"): + if line.startswith("medium.com:"): + medium_token = line.split("medium.com:")[1] + + if medium_token != "\n": + medium_token = medium_token.strip() else: - medium_token = input("Enter your medium token: ") - replace_line("keys.txt", 2, f"medium.com:{medium_token}\n") - + medium_token = input("Enter the Medium API Token: ") + replace_line("keys.txt", 1, f"medium.com: {medium_token}\n") - header = {"Authorization": "Bearer " + medium_token, "Content-Type": "application/json"} + header = { + "Authorization": "Bearer " + medium_token, + "Content-Type": "application/json", + } - medium_id = json.loads(requests.get(USERNAME_ENDPOINT, headers=header).content)["data"]["id"] + medium_id = json.loads(requests.get(USERNAME_ENDPOINT, headers=header).content)[ + "data" + ]["id"] API_ENDPOINT = f"https://api.medium.com/v1/users/{medium_id}/posts" @@ -32,26 +31,32 @@ def medium(article, output): for key in article: post[key] = article[key] - filename = post['title'].replace(" ", "_").lower() + filename = post["title"].replace(" ", "_").lower() output_file = output / f"{filename}_medium_post.md" medium_content = "" with open(output_file, "w") as f: medium_content += f"## {post['title']}\n\n" if post["cover_image"]: - medium_content += f"![{post['title']} 's cover image]({post['cover_image']})\n\n" + medium_content += ( + f"![{post['title']} 's cover image]({post['cover_image']})\n\n" + ) - medium_content+= post["body_markdown"] + medium_content += post["body_markdown"] f.write(medium_content) if post["published"] == "true": - status="public" + status = "public" else: - status="draft" - - - request_josn = {"title": post["title"], "contentFormat": "markdown", "content": medium_content, "publishStatus": status} + status = "draft" + + request_josn = { + "title": post["title"], + "contentFormat": "markdown", + "content": medium_content, + "publishStatus": status, + } response = requests.post(API_ENDPOINT, headers=header, json=request_josn) diff --git a/crossposter/utils.py b/crossposter/utils.py new file mode 100644 index 0000000..1fc3af8 --- /dev/null +++ b/crossposter/utils.py @@ -0,0 +1,8 @@ + +def replace_line(file_name, line_num, text): + lines = open(file_name, "r").readlines() + print(lines) + lines[line_num] = text + out = open(file_name, "w") + out.writelines(lines) + out.close() diff --git a/setup.py b/setup.py index 921a33a..cfac289 100644 --- a/setup.py +++ b/setup.py @@ -3,16 +3,22 @@ HERE = pathlib.Path(__file__).parent -VERSION = "0.0.1" +VERSION = "0.3.1" PACKAGE_NAME = "crossposter" AUTHOR = "Meet Gor" AUTHOR_EMAIL = "gormeet711@gmail.com" URL = "https://github.com/Mr-Destructive/crossposter" -DESCRIPTION = "Crosspost your markdown articles to devto, medium, codenewbie and hashnode" +DESCRIPTION = ( + "Crosspost your markdown articles to devto, medium, codenewbie and hashnode" +) README = (pathlib.Path(__file__).parent / "README.md").read_text(encoding="utf-8") -INSTALL_REQUIRES = ["requests", "python-frontmatter",] +INSTALL_REQUIRES = [ + "requests", + "pyyaml", + "python-frontmatter", +] setup( name=PACKAGE_NAME, @@ -25,9 +31,5 @@ url=URL, install_requires=INSTALL_REQUIRES, packages=find_packages(), - entry_points={ - "console_scripts": [ - "crosspost = crossposter.app:main" - ] - }, + entry_points={"console_scripts": ["crosspost = crossposter.app:main"]}, )