toge's diary

コンピュータ関連の趣味をつらつらと。

既存のPDFをPoDoFoで変換

ふとしたことでそこらへんに転がっているPDFを加工したいことがあります。
PDFを生成するライブラリではなくて、PDFのパーザが必要になるのですがC++でやるには何がいいんですかね〜。

今回は、ざっと探して最初に見つかったPoDoFoを使おうと思ってます。
PoDoFo

ライセンスがLGPLv2なのがちょっと気に入りませんが、ちょっとしたツールを作るだけなので問題ありません。
2014年で開発止まっているようですが、今のところ問題なく使えます。
cmakeを使っているのも好印象。
命名規則がかなりごちゃごちゃなのがちょっと気になりますが。
(GetPageCount()だったり、GetNumAnnots()だったりするんです。)

残念ながらサンプルはPDFの生成しか無いし、ドキュメントはDoxygenでのクラスリファレンスなのでぱっと見使い方が分かりません。
PoDoFo ToolsとしていろいろPoDoFoライブラリを使ったツールが公開されているので、これを触りながら使い方を理解してます。
http://podofo.sourceforge.net/tools.html#tools

どうやら、PDFの編集をする一番楽な方法は全部メモリに読み込んで、編集して、書き出す方法のようなので、これに習おうと思います。
ちゃんと理解すればStream処理もできるのかもしれませんが、とりあえず後回し。

奇数頁だけ削除して書き出すプログラムを書いてみました。

#include <iostream>
#include <podofo/podofo.h>

int main(int argc, char* argv[]) {
  if (argc < 3) {
    std::cout << "usage : "
              << argv[0]
              << " <input file> <output file>"
              << std::endl;
    return 1;
  }

  PoDoFo::PdfMemDocument pdfdoc(argv[1]);
  int page_number = pdfdoc.GetPageCount();
  for (int index = page_number - 1; index >= 0; --index) {
    if (index % 2 == 0) {
      continue;
    }
    pdfdoc.DeletePages(index, 1);
  }
  pdfdoc.Write(argv[2]);

  return 0;
}

PdfMemDocumentというクラスを使うのがキモですね。
ファイル名を渡せばPDFの構造としてメモリの読み込んでくれます。
DeletePagesでメモリ上の情報から指定ページだけ決して、最後にWriteでファイル書き出し。
案外簡単。


PDFによっては次のようなメッセージがでちゃいます。
消したページを参照している処が問題起こしてるのかな。
これもおいおい対応できるようにしたいですね。

WARNING: Treating object 110 0 R as a free object.

まあ、この程度ならプログラム書かなくてもできちゃうので、もう少し中身を弄れるようになりたいところです。

最近のC++に追い付こうと思います

C++で書きなぐるがの楽しかったのですが、そろそろ限界を感じてきたので、C++14とかをちゃんと勉強しようと思ってます。
私はC++98の知識しかないので、ここ2、3年のドラスティックな変化に全然対応できないと痛感してます。

ひとまず以下をサクっと読んで文法的には理解したので、色々調べながら追いつくしかないですね。
www.apress.com

シンプルな構成のC++のHTTPクライアントライブラリは無いものか

「libcurl使えば一発じゃん」と言われればそれまでなのですが、
C++界隈の一部ではheader only libraryが大人気なわけです。

Boostやfollyみたいなガチなものから、もっとホビーなものまで沢山あるのに、
案外無いのがHTTPクライアント。
C++バリバリな方々はそもそもクライアントサイドは作らないのかな。

もう10年近く前の記事で取り上げたHappyHTTPを未だに使ってます。
toge.hatenablog.com

あの当時はまだ開発続けてくれると思ってたんだがなぁ。
全く進化なし。
取り敢えずcallbackの仕組みとかが古臭いのでlambda使ったり、enum class使ったりちょいちょい弄ってますが、
C++11/14の機能を巧みに使った素敵なライブラリを誰か作ってはいないものか。

C++ Requestsとか相当いい線行ってるんですけどね、libcurl依存なのよね。
github.com

Linuxでrarを解凍

忘れた頃に必要になるrarファイル。
ちょっと変なフォーマットだと、Gnomeの機能では解凍できないのよね。

昔は重宝したunrarなんてコマンドは最近のLinux(Fedora 23)にはなかったので、
野良ビルドすることに。

UnRar-5.3.9

ここらへんにあるとおり実行して、
できたunrarを適当に配置すればあっさり使えます。

$ tar xvf unrarsrc-5.3.8.tar.gz 
$ cd unrar
$ make
$ cp unrar /usr/local/bin

最新のフォーマットにも対応しているし、にほんご入りファイル名を処理できました。
めでたしめでたし。

Dockerで簡単にElasticsearch+Kibana環境

自分用のメモ。

ちゃんとやるにはpluginとか色々必要ですし、ネットワークも適切な設定が必要ですが、
まあとりあえず開発で最新版を使いたい時用手順です。

環境はFedora23 workstationです。

$ docker run -d -p 9200:9200 -p 9300:9300 -v "$PWD/esdata":/usr/share/elasticsearch/data elasticsearch:2
$ curl -XGET http://localhost:9200/
{
  "name" : "Runner",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "2.1.1",
    "build_hash" : "40e2c53a6b6c2972b3d13846e450e66f4375bd71",
    "build_timestamp" : "2015-12-15T13:05:55Z",
    "build_snapshot" : false,
    "lucene_version" : "5.3.1"
  },
  "tagline" : "You Know, for Search"
}

なんか立ち上がったっぽいですね。

$ tree $PWD/esdata
esdata
└── elasticsearch
    └── nodes
        └── 0
            ├── _state
            │   └── global-2.st
            ├── indices
            └── node.lock

5 directories, 2 files

カレントディレクトリの下にesdataディレクトリができて、結構デカイデータが入るので注意。

$ docker ps
0c4e128e4145        elasticsearch:2     "/docker-entrypoint.s"   19 minutes ago      Up 19 minutes       0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   stoic_panini

とりあえず立ち上がってるね。よしよし。
次はKibanaだ。

$ docker run -e ELASTICSEARCH_URL=http://192.168.1.101:9200 -p 5601:5601 -d kibana

"192.168.1.101"はホストのIPアドレスを指定。
localhostだとKibanaのコンテナ自信のポートになっちゃうから注意。

$ curl -X GET http://localhost:5601/
<script>var hashRoute = '/app/kibana';
var defaultRoute = '/app/kibana';

var hash = window.location.hash;
if (hash.length) {
  window.location = hashRoute + hash;
} else {
  window.location = defaultRoute;

とりあえず動いてるっぽいですね。
後でブラウザから確認しましたが4.3.1が入ってました。(2016/1/12時点)

$ docker ps 
c41219f376f4        kibana              "/docker-entrypoint.s"   5 minutes ago       Up 5 minutes        0.0.0.0:5601->5601/tcp                           kibana-test02
0c4e128e4145        elasticsearch:2     "/docker-entrypoint.s"   19 minutes ago      Up 19 minutes       0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   stoic_panini

ポートもばっちり。

http://localhost:5601/にアクセスするとちゃんとKibanaの画面がでてきて、満足。

volumioはcronが無効になってる

Raspberry Pi 2のディストリビューションをRaspbianからVolumioにしたんだけど、
cronがことごとく動いていなかった。

ポリシーで無効になってるのか。
www.raspyfi.com

chkconfig --add cron
service cron start

でちゃんと動くようになりました。
ぐぬぬ、1週間ぐらいデータが欠損しちゃったよ。

県庁おもてなし課

文庫版が出てたので買いました。
ちょうど半分読んでみた。
今のところ展開はいつも通りさてここからどうなる?

楽しみにしつつ今日はここまで。