Python argparseでHugo投稿用のコマンドセットを作る. [Vol.1] 要件編

新記事作成時の要件。

『Hop Step Go Hugo』の2回目の記事です。
ブログを投稿するための便利コマンド作成1回目。

本記事では、まず『新記事』作成時の要件を見ていきます。
因みに、本記事は以下のコマンドで生成しています。
画像生成オプションは使わずに、ターミナルのスクリーンショット画像をアイキャッチに指定しました。

> gohugo draft new --target design_hugo_post_flow_command --date 202302122350 --tags "hugo development blog hopstepgohugo python" --categories "雑記" --title "Python argparseでHugo投稿用のコマンドセットを作る. [Vol.1] 要件編" --description "新記事作成時の要件。"

  SUCCESS
目次 - CLICKで開閉します -

はじめに

前回はこのブログの運用フローについて書きました。
今回は記事投稿のフローを効率化するために、まずは新規記事作成コマンドの要件と実現方法を纏めます。
次回は出来上がった新記事作成コマンドのソースコードを見ていきながら、各処理の解説をします。

Hugoを運用される方の何かのヒントになれば幸いです。

機能要件

  1. 新記事を作成する(hugo newと同等の機能)
  2. 新記事作成時、タイトル、サブタイトル、カテゴリ、タグ、日付のフロントマターを指定可能にする
  3. 新記事作成時、セクション名の指定だけで記事作成できるようにする。
    (hugo newでは content/ からの相対パスを指定する必要がある)
  4. 新記事作成時、タイトル画像(アイキャッチ)を自動的に生成できるようにする ※1番重要
  5. 新記事作成時に色々チェックをする。

費用対効果

作成期間

15時間前後(毎日ちょっとづつ実装したとして、約1週間以内で作る)

効果見積もり

  • 新規作成コマンドの効果で、記事1件あたり、20分の短縮
  • 新規作成以外のコマンドと組み合わせることで、記事1件あたり、合計30分の短縮
  • 月に10回投稿するとして、月間300分(5時間)の短縮
  • コマンド一発作成で済む『安心感』、プライスレス。

記事作成時間は1件あたり、2時間と仮定すると、単純計算で25%の時間短縮。
これだけでも、なかなか良いのでは無いでしょうか。

実現方式

1. Pythonのargparseで実現

コマンドの引数指定をルール化したり簡単に受け取ったり、コマンドヘルプをいい感じに表示させることができます。 以下は実装イメージです。


def do_draft_new(args):
  # gohugo draft new の処理実装

# パーサーを作成
mainparser = argparse.ArgumentParser(prog="gohugo", description="gohugo tools.")
subparsers = mainparser.add_subparsers()
p_draft = subparsers.add_parser("draft", help="", description="")
draft_sp = p_draft.add_subparsers()

# ---------------------------------------------------------
# draft new用のサブパーサーを作成
# ---------------------------------------------------------
sp_draft_new = draft_sp.add_parser("new", help="記事を新規作成します", description="")
sp_draft_new.add_argument("--target", required=True, help="content/posts配下に作成するセクション(URL部分)を指定します。(必須)")
sp_draft_new.add_argument("--images", action="store_true", required=False, help="デフォルトアイキャッチを生成します。")
sp_draft_new.add_argument("--ititle", metavar="ITITLE", required=False, help="デフォルトアイキャッチに表示するタイトルテキストを指定します。")
sp_draft_new.add_argument("--title", required=False, help="記事タイトルを指定します。")
sp_draft_new.add_argument("--description", metavar="DESC", required=False, help="概要テキストを指定します。")
sp_draft_new.add_argument("--categories", metavar="CATGS", required=False, help="カテゴリを半角スペース区切りで指定します。")
sp_draft_new.add_argument("--tags", required=False, help="タグを半角スペース区切りで指定します。")
sp_draft_new.add_argument("--date", default=create_default_date(), required=False, help="投稿日時を「YYYYmmddHHMMSS」形式指定します。")
sp_draft_new.set_defaults(handler=do_draft_new)

pargs = mainparser.parse_args()
pargs.handler(pargs)
  • ArgumentParserのインスタンスを作成して、サブコマンド群を登録するためのSubParsersを作成
  • SubParsersにdraftサブコマンドを登録
  • 更にdraftのサブコマンド群を登録すためのSubParsersを作成
  • その後にdraftnewコマンド用のパーサーと、コマンドオプションを登録しています
  • 最後にコマンド引数をパース(解析)してdo_draft_newコマンドに引数を渡して実行します
既にややこしいですが、これ以外の説明方法が見つかりません。すみません。(笑)

2. アイキャッチ(タイトル画像)生成

tcardgenというgo言語で書かれたツールを使います。
ベースになる背景のみの画像は自分で用意し、コマンドを実行すると記事からフロントマターを読み取り、以下項目を背景画像に合成したものを出力してくれます。

  • タイトル
  • 作者
  • 日付
  • カテゴリ
  • タグ(複数あればその分表示)

tcardgen公式
https://github.com/Ladicle/tcardgen

とても便利ですが、背景画像や描画用のフォント、スタイルを準備する等、若干の手間はあります。

3. コマンドはsubprocess.run

基本的に、Pythonのsubprocess.runでOSのコマンドを実行させます。
想定するOSは、GNU SHELLコマンドが実行可能なLinux, Mac, Windowsです。
難しい場合は実行環境用のDockerコンテナを用意するのも良いと思います。

といっても、GNUコマンド依存になる部分は恐らくsedくらいなので、汎用性を鑑みて、BSD系コマンドでも実行できるように改良するかもしれません。
あとはGitコマンドを多用します。コミットメッセージは全自動で設定、ブランチマージや特定のディレクトリ配下のみ別ブランチにチェックアウトさせたりします。

LinuxのコマンドSHELLにはGNU系とBSD系があります。今回はGNUコマンドについての説明は割愛します。

次回はスクリプト紹介

次回の『Hop Step Go Hugo』では、Draft記事操作のコマンド全貌について見ていきます。

『ブログに書くことで、新たに改良点を見出せるかもしれない』という希望も含めて。

それでは、良いCoffeeを。



関連記事