Coder Social home page Coder Social logo

qiita's Introduction

Qiitaの記事をGitHubで管理してTravisCI経由で自動投稿する(Python)

Qiita に記事を投稿したいと思っていましたが、記事を書くのは面倒くさい上に手元に好きなエディタも使えないしなぁと感じていたところ、以下の記事を見つけました。

GitHubへのpushと同時に自動で出来たらこんな素晴らしいことはないなと思ったので、丸パクリしたいと思いました。ただ、丸パクリしても全然自分のためにはならないので、Rubyで実現されていたものをPythonに変更することにしました。

Qiita個人用アクセストークン取得

Qiita-設定-アプリケーションで個人用アクセストークンを新しく発行します。 以下のスコープにチェックを入れて、発行します。

  • read_qiita
  • write_qiita

表示されたアクセストークンは二度と表示されないので、コピーします。

Qiita APIv2 ライブラリ

Qiita API v2のPythonラッパー実装したの通りに、qiita_v2をインストールします。

ライブラリの動作確認を行います。 config.yamlファイルにACCESS_TOKENとして、トークンを記述しておきます。

from qiita_v2.client import QiitaClient

config_file = "config.yaml"
user_name = "hogehoge"
client = QiitaClient(config_file=config_file)
response = client.get_user(user_name)
print(response.to_json())

実行してみます。

$ python deploy_test.py
/home/<user_name>/github/qiita/venv/lib/python3.7/site-packages/qiita_v2/client_base.py:36: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
  config = yaml.load(f)

すると、何か Warning が出力されていて煩いので、ここを参考に修正します。

@@ -33,7 +33,7 @@
         self.team = team
         if config_file:
             with open(config_file, 'r') as f:
-                config = yaml.load(f)
+                config = yaml.safe_load(f)
                 if 'ACCESS_TOKEN' in config:
                     self.access_token = config['ACCESS_TOKEN']
                 if 'TEAM' in config:

Qiita投稿用スクリプトを作成

投稿用のスクリプトを作成します。 QiitaClientにアクセストークンを渡す方法でやってみたのですが、Unauthorizedと言われてしまうので、ヘッダにトークンを追加するようにしてみました。

import os
import json

from qiita_v2.client import QiitaClient


params_file_path = 'item/params.json'
body_file_path = 'item/README.md'
item_id_file_path = 'item/ITEM_ID'

client = QiitaClient(access_token='dummy')

headers = {'Content-Type': 'application/json',
           'Authorization': 'Bearer {}'.format(os.environ['QIITA_TOKEN'])}

with open(params_file_path) as f:
    params = json.load(f)

with open(body_file_path) as f:
    params['body'] = f.read()

if os.path.exists(item_id_file_path):
    with open(item_id_file_path) as f:
        item_id = f.read()
    res = client.update_item(item_id, params, headers)
    print(res.to_json())
else:
    res = client.create_item(params, headers)
    print(res.to_json())

タイトル・タグ

タイトルやタグは、item/params.jsonで定義します。

{
  "title": "Qiitaの記事をGitHubで管理してTravisCI経由で自動投稿する(Python)",
  "tags": [
    {
      "name": "Github",
      "versions": []
    },
    {
      "name": "TravisCI",
      "versions": []
    }
  ],
  "coediting": false,
  "gist": false,
  "private": false,
  "tweet": false
}

item/ITEM_IDに更新したい記事のIDを保存すると、そのIDの記事を更新するようになります。 item/ITEM_IDファイルがなければ、新たに記事を作成します。

Qiitaアクセストークン

Qiitaのアクセストークンについては、環境変数としてQIITA_TOKENに設定します。

$ export QIITA_TOKEN=<access_token>

お試し投稿

これで投稿できるようになったので、手元から直接Qiitaに投稿してみます。

$ python deploy.py

Qiitaを覗いてみると、きちんと投稿できてました。

いよいよ、TravisCI経由で自動投稿します

travis CLI が使いたいので、インストールしておきます。

$ gem install travis

travis login

何回やってみても失敗してたけど、Travis CIにログインして設定周りを見ていたりして、再度試してみたら、ログイン出来た...理由は分かりません...

$ travis login
We need your GitHub login to identify you.
This information will not be sent to Travis CI, only to api.github.com.
The password will not be displayed.

Try running with --github-token or --auto if you don't want to enter your password anyway.

Username: <user_name>
Password for <user_name>: ********
Successfully logged in as <user_name>!

travis init

またまた、何回か失敗していたりしていましたが、travis-ci.orgに行ってみたら、登録したはずのGithubのレポジトリがなかったりしたので、Githubリポジトリを再度登録して、再度travis initしてみたらOKでした。理由は分かりません...

(venv) ~$ travis init
Main programming language used: |Ruby| Python
.travis.yml file created!
<user_name>/qiita: enabled :)

これで、.travis.ymlが初期作成されます。

アクセストークンの暗号化

Qiitaのアクセストークンは暗号化して、.travis.ymlに追加します。

$ travis encrypt QIITA_TOEKN=<access_token> --add
Overwrite the config file /home/<user_name>/github/qiita/.travis.yml with the content below?

This reformats the existing file.

---
language: python
python:
- '2.7'
- '3.3'
- pypy
env:
  global:
      secure: <secure-key>
(y/N)
y

デプロイスクリプトの有効化

.travis.ymlを以下のように描きます。

  • masterブランチ以外のコミットでは動かない
  • ライブラリのインストールを記述
language: python
python:
- '3.7'
branches:
  only:
  - master
install:
- pip install -r requirements_travis.txt
script:
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then python deploy.py; fi'
env:
  global:
    secure: XXX

ライブラリは以下のようにして出力しておきます。

$ pip freeze > requirements_travis.txt

運用方法

さて、最後に、このレポジトリの運用方法についてですが、スクリプトはこのリポジトリのitemディレクトリに含まれるREADME.mdを記事として投稿します。そして、その記事のタイトルなどは、params.jsonに設定します。 つまり、新しい記事は常にitemディレクトリに配置しておく必要があります。 そこで、以下のように運用していきたいと思います。

注意事項: 記事に画像を入れるとき

Qiitaでは、画像はAmazon S3に格納しているようです。 したがって、QiitaのWeb編集インターフェイスで、 画像だけはドラッグ&ドロップでその記事上に置いた上で、 そのリンクアドレスを記事にも反映します(面倒ですね...)。

新しい記事を作成するとき

  1. item_XXX(XXXは文字通り'XXX'という文字列)ディレクトリを作成する
  2. そのディレクトリの配下にREADME.md,params.jsonを作成する
  3. itemからitem_XXXにシンボリックリンクを貼る
  4. git で commit & push する
  5. 記事の作成が成功したら、その記事のITEM_ID(URLに含まれている文字列)をコピーする
  6. item_XXXitem_$ITEM_IDに変更し、そのディレクトリの中にITEM_IDというファイルを作成する
    • ITEM_IDファイル中の改行は削除しないと駄目みたいです(面倒です...)。
    • tr -d '\n' < ITEM_ID > ITEM_ID.bak
    • mv ITEM_ID.bak ITEM_ID
  7. git で commit & push する

既存の記事を更新するとき

  1. シンボリックリンクitemから更新したい記事のディレクトリにリンクを貼る
  2. 記事を更新する
  3. git で commit & push する
  4. シンボリックリンクitemを削除する

qiita's People

Contributors

naomori avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.