LoginSignup
1
0

More than 5 years have passed since last update.

Qiita:TeamからMarkdownを保存するまで

Last updated at Posted at 2017-09-13

前回のおさらい

QiitaもしくはQiita:Teamからmdをダウンロードするコード

Qiita:Teamからデータを移行するかもしれないので、データのダウンロードのみ行ったよって状態でした。
実際の中身はjsonのbodyにmarkdownが入ってるので、それを引っ張ってくれば良いだけでした。

なんだそりゃって感じです。

urlに.mdをつけてダウンロードしようとしたのですが、ログイン画面のダウンロードになり、思惑失敗という形です。
ブラウザ開発者の方はログインさえできてしまえば、URLに.mdとつければ良いのでお手軽だと思います。

コードを書いた結果

今回は、お昼前に1時間、お昼後に3時間pythonと格闘してました。
すると、pythonのラッパー作ってる人がいて絶句しましたけどね…。

主に苦戦したのはglobal変数の使い方ですけど、なぜ値が入ってこないんだ!と思ってたら、global宣言した時のみ最後の値が反映される、という仕様であることに気づき、なるほどなぁ、となってました。

#!/usr/bin/env python
# coding: utf-8

import os
import sys
import json
import urllib.request
import urllib.parse

url = ''
apiKey = ''
teamName = ''
api = '/api/v2/items?per_page=100'
pageApi = '&page='
pageCount = 0
maxCount = 0

def argmentscheck():
    global url
    global apiKey
    global teamName
    global api

    url = ''
    apiKey = ''
    teamName = ''
    api = '/api/v2/items?per_page=100'

    if len(sys.argv) == 2:
        apiKey = sys.argv[1]
        url = 'https://qiita.com'
        print('Qiitaからデータを抜き出します')
    elif len(sys.argv) == 3:
        apiKey = sys.argv[1]
        teamName = sys.argv[2]
        url = 'https://' + teamName + '.qiita.com'
        print('Qiita:Teamの' + teamName + 'からデータを抜き出します')
    else :
        print('引数の数が何かおかしいです')

def createDirectory(createDay, markdownUrl):
    directoryArray = createDay.split('-')
    createPath = "./" + directoryArray[0] + "/" + directoryArray[1]

    if not(os.path.exists(createPath)):
        os.makedirs(createPath)

def getPerPageJsonDownload():
    global pageApi
    global pageCount
    global maxCount

    headers = {"Authorization" : "Bearer " + apiKey}
    requestUrl = url + api

    if pageCount:
        requestUrl = url + api + pageApi + str(pageCount)

    request = urllib.request.Request(requestUrl, None, headers)
    response = urllib.request.urlopen(request)
    responseHeader = str(response.info())

    if maxCount == 0:
        headerList = []
        headerDict = {}
        for headerOneline in responseHeader.split('\n'):
            for oneWord in headerOneline.split(': '):
                if len(oneWord):
                    headerList.append(oneWord)
        headerDict = dict(zip(headerList[0::2], headerList[1::2]))
        maxCount = headerDict['Total-Count']

    jsonRaw = response.read().decode('utf-8')
    json.dumps(jsonRaw, ensure_ascii=False)
    return jsonRaw

def fileWriting(createDay, markdown, title):
    markdownTitle = title.replace('/', ' ') + '.md'
    directoryArray = createDay.split('-')
    createPath = "./" + directoryArray[0] + "/" + directoryArray[1] + "/" + markdownTitle

    writeFile = open(createPath, 'w')
    writeFile.write(markdown)
    writeFile.close()

def main():
    global pageCount

    jsonRaw = getPerPageJsonDownload()
    jsons = json.loads(jsonRaw)
    for count in range(round(int(maxCount)/len(jsons))):
        pageCount += 1
        for oneWrote in jsons:
            createDirectory(oneWrote['created_at'], oneWrote['url'])
            fileWriting(oneWrote['created_at'], oneWrote['body'], oneWrote['title'] )
        jsonRaw = getPerPageJsonDownload()
        jsons = json.loads(jsonRaw)

if __name__ == '__main__':
    argmentscheck()
    main()

あ、前回の記事で一個誤りがありました。
pageの考え方がないものだと思っていたら、Qiitaにもpageの考え方がありました。
その内容が盛り込まれています。

Qiita APIからpageを取得する場合、headerにTotal-Countが存在しますので、うまく取り出すようにします。
取り出し方としては、以下のようになります。

    if maxCount == 0:
        headerList = []
        headerDict = {}
        for headerOneline in responseHeader.split('\n'):
            for oneWord in headerOneline.split(': '):
                if len(oneWord):
                    headerList.append(oneWord)
        headerDict = dict(zip(headerList[0::2], headerList[1::2]))
        maxCount = headerDict['Total-Count']

最初だけQiitaの記事数の最大値がわからないので、処理が無駄にならないよう、最初のみ実行させています。
responseHeaderは、改行区切りになってますので、splitで分割し、さらに:{space}で改めて分割し直してます。
headerがこの仕様じゃなかったらわなわなと震えてるところでした。

これ、Qiita:Team仕様にしてますので、Qiitaで流した場合、トークンの上限に達するまで延々取得し続けますのでご注意ください(ぉぃ
タイトルをファイル名にしてますが、詰めが甘く、/が含まれる場合は、{space}に置き換えてます。
先頭に.がある場合は考慮されていません。
考慮したい場合は、以下にコーディングを足していただければと思います。

markdownTitle = title.replace('/', ' ').replace('.', {.に変わる何か}) + '.md'

これからやること

残タスクはざっとこんな感じです。

  • Qiita:Teamからイメージを取得する処理
  • Qiita:Team内の画像パスを相対パスに書き換える対応

できたらまた記事投稿します。お元気で。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0