私の周りでは、情報管理にesaを使っている方が非常に多いです。
esaは私も使っていますが、以下のようなメリットがあり、とても便利です。
- WIPの状態でも公開できる
- 情報の検索がしやすい
- 更新の履歴が追える
顧客との打ち合わせの議事録もesaにまとめるチーム・会社も多いそうです。
齟齬をなくすため顧客にも議事録内容を共有する際に、わざわざesaの内容をWordファイルに編集し直したり、それをPDFに変換している、という声をある方から聞きました。
それが面倒で、最初からWordファイルに書くようになり、esaなどで共有されなくなってしまった、という状態になっているそうです。
それはかなり無駄だと思うので、自動でWordとPDFファイルを自動生成ツールを作ってみました。
構成概要
社内の特定のPCにWebサーバを立てて、皆がそこにアクセスしてツールを使えるようにしたいなと思いました。特にこだわりはないのですが、慣れているのでRとShinyを使ってWebサーバを立てるようにしました。
また、Pandocというツールを使うことで、markdown形式のファイルをWordやPDFにすることができます。
ただし、環境構築がちょっと面倒なので、Dockerを使うことにしました。
完成イメージ
まず、esaの記事idを数値入力し、「Markdownを取得」ボタンを押すことで、記事内容の取得を行います。
またその際に、markdownからWordファイルやPDFファイルをPandocで生成します。
その後、「Download Word」や「Download PDF」をクリックすることで、生成されたファイルをダウンロードできます。
実際に作成
コードは以下に置きました。Dockerfile
すでにShiny環境が入った、rocker/shinyというDockerイメージがあるので、それをベースに作成します。以下のようにDockerfileを作成します。
FROM rocker/shiny:3.6.3 RUN apt update && apt install -y libcurl4-openssl-dev libssl-dev RUN apt-get install -y texlive-latex-base texlive-fonts-recommended texlive-latex-recommended texlive-lang-cjk texlive-luatex texlive-xetex RUN R -e "install.packages(c('httr', 'dplyr'), dependencies=T)"
rocker/shiny:3.6.3 をベースにして、イカを追加しています。
- 4行目では、pandoc用のツール群をインストール
- 5行目では、Rのライブラリである以下インストール
- httr(esaのAPIを使用するための、httpアクセス用ライブラリ)
- dplyr(パイプで処理を書く用のライブラリ)
- 3行目では、httrライブラリを使うための、ツール群をインストール
esaのAPI KEY
esaのAPIを使うためには、アクセストークンとesaのチーム名が必要があります。詳しくは公式サイトをご覧ください。
RからesaのAPIを叩く方法については、以下記事を参考にしました。
esaのAPI用のアクセストークンは、環境変数で持っていた方が扱いやすそうだが、通常のRコンソールでは使用できてもShiny上に渡せないことが分かったので、ちょっと辛いですが、esa_info.csv というファイルで管理することにしました。
以下のように、esa_info.csv というファイルを作って、その中に、アクセストークンとチーム名を書いておいてください。
(XXXXXXXX という部分を取得したトークンやチーム名に置換する)
ESA_API_KEY,ESA_TEAM_NAME XXXXXXXXXXXXXXXXX,XXXXXXXX
ui.Rとserver.R
app.Rという1つのファイルで書いても良かったのですが、一応ui.Rとserver.Rに分けています。ui.R
library(shiny) shinyUI(fluidPage( titlePanel("esa記事をWord or PDFで出力"), sidebarLayout( sidebarPanel( numericInput("numericInput_data", "esaの記事IDを入力", min = 1, value = 1), actionButton("render_md", "Markdownを取得"), br(), uiOutput("download_files") ), mainPanel( verbatimTextOutput("text") ) ) ))
server.R
library(shiny) library(httr) library(dplyr) esa_info <- read.csv("esa_info.csv") headers <- httr::add_headers(`Authorization` = paste("Bearer", esa_info[1, 1]), `Content-Type` = "application/json") team_name <- esa_info[1, 2] shinyServer(function(input, output) { output$text <- renderText({ paste(markdown_text()) }) markdown_text <- reactive({ input$render_md input_id <- isolate(input$numericInput_data) api_result <- GET("http://api.esa.io", path = paste("v1/teams", team_name, "posts", input_id, sep = "/"), config = headers) if (api_result %>% status_code() != 200){ return(paste("API Error:", api_result %>% status_code())) } contents <- api_result %>% content() write(contents$body_md, paste("www/sample_", input_id, ".md", sep="")) system(paste("pandoc -f markdown -t docx www/sample_", input_id, ".md -o www/sample_", input_id, ".docx", sep="")) system(paste("pandoc -t latex www/sample_", input_id, ".docx -o www/sample_", input_id, ".pdf --pdf-engine=xelatex -V documentclass=bxjsarticle -V classoption=pandoc", sep="")) return(contents$body_md) }) output$download_files <- renderUI({ input_id <- input$numericInput_data tagList( h3(tags$a(href=paste("sample_", input_id, ".docx", sep=""), target="blank", "Download Word", download=paste("sample_", input_id, ".docx", sep=""))), h3(tags$a(href=paste("sample_", input_id, ".pdf", sep=""), target="blank", "Download PDF", download=paste("sample_", input_id, ".pdf", sep=""))), ) }) })
server.Rでは、まずesa_info.csv からトークン情報やチーム名を取得しています。
その後、ui.Rから渡ってきた記事IDを元にesa APIにアクセスして、記事情報を取得・WordとPDFファイル作成を行なっています。
ui.Rやserver.R の中身自体は特に難しくないと思うので解説はこのぐらいにしておきます。
docker-compose.yaml
以下のようにdocker-compose用のファイルを作成します。version: '3' services: esa-shiny: container_name: esa-shiny image: esa-shiny:1.0 ports: - 3838:3838 # environment: # - ESA_API_KEY=XXXXXXXXXXXXXXXX # - ESA_TEAM_NAME=XXXXXX volumes: - $PWD/shiny-src:/srv/shiny-server/esa
- イメージは先ほど作成した、「esa-shiny:1.0」
- 3838でポートフォワーディング
- ShinyのソースコードをDockerコンテナ内の /srv/shiny-server/esa にマウント
Dockerコンテナを起動
以下のようなディレクトリ 構成で先ほどのファイルを用意してください。- shiny-src/ - esa_info.csv - ui.R - server.R - www/ - docker-compose.yaml - Dockerfile
その後、以下を実行してDockerイメージを作成します。
$ docker build -t esa-shiny:1.0 .
次に、以下を実行してDockerコンテナを立ち上げます。
$ docker-compose up -d
これでShinyアプリケーションが立ち上がりました。
ブラウザで、【localhost:3838/esa】、もしくは 【今起動しているパソコンのIPアドレス:3838/esa】にアクセス(例 192.168.1.100:3838/esa)してください。
適当なesa記事IDを入力して、WordやPDFファイルを生成できるようになっています。
まとめ
今回は、esa APIとPandocを使ってWordファイルやPDFファイルの作成に挑戦しました。この状態では、簡素なWordファイルが作成されていますが、テンプレートを用いることで見た目をカスタマイズできます。
次回は、その辺りをやっていきます。