Earlier this week, I created a new Blogger tool to support this new Pelican-based blog. It is a simple Python3 tool that accepts a variable number of arguments and then creates a Pelican friendly Markdown file. It will then launch that new file in the Markdown editor of your choice. In my case it launches Visual Studio Code. Here is an example:
$ blogger.py New Python Blogger Tool
Creating: 2021-04-17-new-python-blogger-tool.md
And since I hate typing repetitive words, in my .zshrc
I have the following line to simplify launching the blog editor to simply b
:
alias b=blogger.py
Sample call to the tool:
$ b New Python Blogger Tool
Creating: 2021-04-17-new-python-blogger-tool.md
The code is not too advanced so I will just put it below. The script requires:
- Python 3.6+ for f-strings
- pyyaml from pip
You will probably notice a custom util and path module. Those are just simple helper modules. The main functions used.
- path.canonize() - Converts paths like
~/folder/../folder2
into/Users/emartin/folder2
. Seeos.path.normpath()
andos.path.expanduser()
in the built-inos
module. - util.log() - My console logger with time stamps. Easily replaceable with a
print()
statement.
I would post the link to my Github repo, but it is a private and it would take me a while to extract secrets. Maybe one day soon. Here is the code:
#!/usr/bin/env python3
import argparse
import os
import path
import util
import run
# pip install pyyaml
import yaml
# Backup configuration needs to live in the same location as script
__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
config_yaml = "blogger_config.yaml"
config_yaml_path = os.path.join(__location__, config_yaml)
def blogger(config, title):
source_folder = path.canonize(config['source_folder'])
# Validate source folder exists
if not os.path.exists(source_folder):
util.log(f'ERROR: Source folder does not exist: {source_folder}')
return -1
content_folder = os.path.join(source_folder, 'content')
# Validate content folder exists
if not os.path.exists(content_folder):
util.log(f'ERROR: Content folder does not exist: {content_folder}')
return -1
# Generate the file name from the date and passed in title
today = util.todaysDate()
year = '{:%Y}'.format(today)
month = '{:%m}'.format(today)
day = '{:%d}'.format(today)
name = title.lower().replace(" ","-")
filename = f'{year}-{month}-{day}-{name}.md'
new_blog_file = os.path.join(content_folder, filename)
# Only create the file if the file doesn't exist otherwise just open it
if not os.path.exists(new_blog_file):
# Get the metadata defaults from the config file
category = config['category']
tag = config['tag']
author = config['author']
# Write metadata to top of the file in yaml format
print(f'Creating: {filename}')
with open(new_blog_file, 'a') as f:
f.write(f'Title: {title}\n')
f.write(f'Date: {today}\n')
f.write(f'Category: {category}\n')
f.write(f'Tags: {tag}\n')
f.write(f'Authors: {author}\n')
# Launch Markdown Tool
markdown_tool = path.canonize(config['markdown_tool'])
run.launch_app(markdown_tool, new_blog_file)
# Main function
if __name__ == '__main__':
# Parse arguments
parser = argparse.ArgumentParser(description='Script to automate blogging.')
parser.add_argument('title', help=f'The title of the blog.', nargs='*', default='')
args = parser.parse_args()
# Dump Help if no parameters were passed
if (len(args.title) == 0):
parser.print_help()
exit(0)
# Load configuration file
config = {}
with open(config_yaml_path) as file:
config = yaml.full_load(file)
# Run Blogger
title = " ".join(args.title)
return_code = blogger(config, title)
exit(return_code)
And the blogger_config.yaml looks like this:
source_folder: ~/Source/blog.emrt.in
category: "Misc|Media|Technology"
tag: "Blog"
author: Erik Martin
markdown_tool: /Applications/Visual Studio Code.app/Contents/Resources/app/bin/code
Descriptions of the configuration:
- source_folder - Where the Pelican blog source is located. Files are created in the content folder.
- category - category of the post (blog entry metadata)
- tag - comma separated tags of the post (blog entry metadata)
- author - default author of the post (blog entry metadata)
- markdown_tool - The path to the markdown tool that launches the created .md file