トップ 追記

アペフチ


2013年05月21日 EverpadはSQLiteを使っていた [長年日記] この日を編集

_ [Linux] EverpadはSQLiteを使っていた。

この前Everpadを入れたけど、あのデータってどこにあるんだろうと思って、当てずっぽで探してみたら、~/.everpadというディレクトリーがあったので見てみた。
 $ ls -a ~/.everpad/
 .  ..  data  everpad.5.db
dataは、添付した画像とかのファイルみたい。で、データベースの方は、
 $ file ~/.everpad/everpad.5.db
 /home/kitaitimakoto/.everpad/everpad.5.db: SQLite 3.x database

_ ということで、SQLiteを使っているみたいだ。実際、sqlite3コマンドで開ける。

 $ sqlite3 ~/.everpad/everpad.5.db 
 SQLite version 3.7.15.2 2013-01-09 11:53:05
 Enter ".help" for instructions
 Enter SQL statements terminated with a ";"
 sqlite> .tables
 notebooks  notes      notetags   places     resources  tags     

2013年05月18日 ディストロのlibxml2が新しくなったんでNokogiriをインストールし直したいんだけどBundler使っているプロジェクトはどうしたらいいんでしょうか。 [長年日記] この日を編集

_ [Ruby][Bundler] ディストロのlibxml2が新しくなったんでNokogiriをインストールし直したいんだけどBundler使っているプロジェクトはどうしたらいいんでしょうか。

他人の褌で日記更新。いつもありがとうございます。

2013年05月16日 Everpad入れてみた [長年日記] この日を編集

_ [Evernote][Ubuntu] Everpad入れてみた

大昔にEvernoteクライアントを探していてNevernoteを入れてみたけど文字化けして以来、パソコン(Ubuntu)ではずっとブラウザーからEvernoteを使っていたのだけど、やっぱりオンラインじゃないと使えないっていうのは大きな制約なので、改めて探して、Everpadっていうのを入れてみた。

_ https://myapps.developer.ubuntu.com/dev/apps/1678/

_ Python製。Calibreもそうだけど、Pythonは普通にGUIを作るのにも使われていて、凄いなあ。

_ 入れ方については無銘闇人の電脳ろぐ: UbuntuとEvernoteの連携: Everpadインストールとかに従えば問題ないんだけど、上のパネル上に Evernote のアイコンである象のアイコンが表示されるので,それをクリックし,「Settings and Management」をクリックというところで、少なくとも現在は、象のアイコンは出ないのでそこだけ補足。

今現在では、下にあるように、象ではなくて「メモ帳と鉛筆」のアイコンになっています。 メモ帳と鉛筆のアイコン

_ Evernoteの権利に配慮したのかな。

つまんない話ですみません、日記のネタが欲しかったんです。


2013年03月31日 EPUB SearchというRubyGemを作った [長年日記] この日を編集

_ [EPUB][Ruby][Groonga] EPUB SearchというRubyGemを作った

EPUB SearchというRubyGemを作りました。

_ ローカルマシンのEPUBファイルをGroongaデータベースに突っ込んで、検索できるようにするgemです。

_ EPUBを読む環境というのはまだまだ全然整っていなくて、僕の場合不満があったのが本内検索。普段のEPUB環境は……

  • 携帯のEPUBリーダーAldiko。これは検索機能はある。
  • FirefoxのEPUBReaderアドオン。これに本内検索がない。
  • 蔵書管理にCalibre。本内検索がない。
  • Murasaki。最近職場のコンピューターをマッキントッシュにしたので。これには本内検索もあるし全然不満はない。

_ という物なので、本の中身を検索するという、PDFなんかでは当たり前のことがやりにくいのです(本内検索ができるリーダーも勿論あるのだけど、それ以外に不満があったりして、今のところこの環境に落ち着いています)。

_ EPUB Searchをインストールすると、マシン上のEPUBファイルをデータベースに突っ込んで、検索できるようになります。

knife-soloを検索したところ

_ 本内どころか、(登録してある)本を横断的に検索できるので、「あー、RubyでStriong#formatにハッシュを渡す方法、どっかの本にあったと思ったけどどこだっけ」みたいな時にも活躍します。本を指定しての検索もできます。

_ 残念ながらコマンドラインツールです。ウェブサーバーもありますが、本の追加とかはできなくて、検索のみです。

インストール

 $ gem install epub-search

使い方

セットアップ

面倒ですが、インストールしただけでは使えなくて、一回セットアップする必要があります。 と、その前に「epub-search」コマンドを打つのが面倒なのでエイリアスを設定しておきます。
alias es=epub-search
alias epsearch="epub-search search"
で、セットアップ。
 $ es init
これで、Groongaデータベースが作成されて、必要なテーブルが定義されます。

本の登録

検索対象にしたい本を登録します。
 $ es add ~/Documents/Books/入門ChefSolo-InfrastructureasCode-1.0.0.epub
まとめて登録することもできます。
 $ es add ~/Documents/Books/*.epub
本を買う度に登録しないといけないのかって? 後ほど「epub-search watch」コマンドをご紹介します。

検索

 $ epsearch knife-solo
ずらずらっと「検索文字を含む行」「タイトル」「場所」のセットが並びます。 本のタイトルで絞り込むには
 $ epsearch サーバー Linux標準教科書
というように、検索語のあとに書名の検索語を入れます。

本の削除

EPUBファイル自体を削除しても、データベースにはデータが残っています。これを消すには
 $ es remove ~/Documents/Books/入門ChefSolo-InfrastructureasCode-1.0.0.epub
とします。

本棚の監視

本のダウンロード→登録→削除→本のファイルの削除
みたいなサイクルを一々回すのは面倒なのであるディレクトリーを監視して、EPUBファイルに変化があればそれをデータベースにも反映させることができます。
 $ es watch ~/Documents/Books/
この状態でファイルの追加・変更・削除があったら、その結果をデータベースに反映させます。 止めるにはCtrl-Cを押します。 これを止めている間のファイルの追加・変更も、es watchした時に反映されるようになっています(削除については対応していないな、そう言えば)。

本の一覧

登録してある本の一覧は
 $ es list
で見られます。

サーバー

 $ es server
で、検索専用のウェブサーバーが立ち上がります。が、試しに作ってみただけ、みたいな感じなのであんまり使えないかも。

_ その他、オプションについてなどは

 $ es help [COMMAND]
としてみてください。

_ 開発はGitHubでやっています。

_ Linux/UNIXの知識に乏しくて分からなかったのですけど、「ログインした時にepub-search watchを実行して、ログアウトした時に切る」っていうのってどうやるんでしょう?

.profile、.bash_profileファイルを使うのかなと思うんですが、一回やったらマシンが立ち上がらなくなった……。

本日のツッコミ(全2件) [ツッコミを入れる]

_ kou [Xを使っているなら~/.config/autostart/以下に*.desktopファイルを置くのが、ログインしたと..]

_ 北市真 [確かに、ログイン時に起動するようになりました! デーモンにしてPIDファイルを作るようにすればログアウト時のことは..]


2013年03月30日 [長年日記] この日を編集

_ 本屋さんにとって、売れる売れないのデータが生で見えるので、売れるものを目に入りやすくレイアウトするのはそうなんだと思う。

_ 出版社のサイトでは、著者への配慮があって、あんまり、差を付けられないのではないかと思う。あと所詮、スペース的には一冊分なのだ。

_ だから、本屋さんに足を運んで、一通り平積みを眺めるのは、意味があるように思う。特に、僕のような、まるでアンテナが狭い人間にとっては。

_ この話は、売上データを棚に反映させているところで、ちゃんと母数の大きいところ、ということになっちゃうと思うけど。


2013年03月21日 EPUB一覧をOPDSで配信するサーバーを作った [長年日記] この日を編集

_ [EPUB][OPDS][Ruby] EPUB一覧をOPDSで配信するサーバーを作った

指定したディレクトリーの下にあるEPUBファイルから情報を抜き出して、OPDSにして配信するサーバー(Rackアプリケーション)を作りました。

_ 使い方。

  1. まずはこのライブラリーと必要なその他のgemをインストールします。
     $ gem install rss-opds rack epub-parser
    
  2. 次にインストールしたところやGitHubからこのファイルをコピーして適当なところに置きます。
  3. ファイルの一番下にある
    
     run OPDSServer.new("#{Dir.home}/Documents/Books")
    
    の「"#{Dir.home}/Documents/Books"」という所を、自分の好きなディレクトリーに書き換えます。このディレクトリー下にあるEPUBファイルの情報をOPDSとして配信します。
  4. サーバーを起動します。
     $ rackup opds_server.ru
    
  5. するとサーバーが立ち上がるので、ウェブブラウザー等でhttp://localhost:9292/(9292の所は違うかも、rackupした時のログを見てください)にアクセスします。 OPDSが配信される

_ これは今のところライブラリーのサンプルとして書いているので結構物足りないところとかあるはずですが(OPDSの項目とか、ファイルをダウンロードできるようにリンクしたいとか、キャッシュ戦略とか)、個人が数冊EPUBを出版しているくらいだったら、割と実用できるんじゃないかなあ。

_ そのうち独立したgemにして配布したいところ。


2013年03月20日 EPUBからOPDSを作る [長年日記] この日を編集

_ [EPUB][OPDS][Ruby] EPUBからOPDSを作る

EPUBからメタデータ情報を抜き出してOPDSのentry要素にしようと思ったらこんな感じだろうか。

_ epub2opds.rb


 require 'epub/parser'
 require 'rss/opds'
 
 epub = EPUB::Parser.parse(ARGV.shift)
 puts RSS::Maker.make('atom') {|maker|
   ch = maker.maker.channel
   ch.about = 'http://example.net/'
   ch.title = 'epub2opds'
   ch.description = 'This is extracted from EPUB files automatically'
   ch.links.new_link do |link|
     link.href = 'http://example.net/'
     link.rel = 'self'
     link.type = RSS::OPDS::TYPES['acquisition']
   end
   ch.date = Time.now
   ch.author = 'epub2opds.rb'
 
   maker.items.new_item do |entry|
     entry.title = epub.title
     entry.updated = epub.metadata.dates.first.to_s
     entry.summary = epub.metadata.descriptions.first.to_s
     entry.id = epub.metadata.unique_identifier.to_s
   end
 }

_ 結果。

 $ ruby epub2opds.rb ~/Documents/Books/入門Sinatra.epub

 <?xml version="1.0" encoding="UTF-8"?>
 <feed xmlns="http://www.w3.org/2005/Atom"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:dcterms="http://purl.org/dc/terms/"
   xmlns:fh="http://purl.org/syndication/history/1.0"
   xmlns:opds="http://opds-spec.org/2010/catalog">
   <author>
     <name>epub2opds.rb</name>
   </author>
   <id>http://example.net/</id>
   <link href="http://example.net/"
     rel="self"
     type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
   <subtitle>This is extracted from EPUB files automatically</subtitle>
   <title>epub2opds</title>
   <updated>2013-03-20T19:32:56.711308+09:00</updated>
   <entry>
     <id>urn:isbn:9784873115597</id>
     <summary></summary>
     <title>入門Sinatra</title>
     <updated>2012-09-20T00:00:00+09:00</updated>
     <dc:date>2012-09-20T00:00:00+09:00</dc:date>
     <dcterms:date>2012-09-20T00:00:00+09:00</dcterms:date>
   </entry>
   <dc:date>2013-03-20T19:32:56.711308+09:00</dc:date>
   <dcterms:date>2013-03-20T19:32:56.711308+09:00</dcterms:date>
 </feed>

_ 個々のEPUBファイルの情報は飽くまでentryであって、フィード全体の作者なんかの情報や載せるEPUBファイルの選択はそれとは関係なく自分で設計しなくてはいけない。

_ 追記。

EPUBからのメタデータの抽出は、EPUBInfoっていうライブラリーがあったのでそれを使ってもいいかも知れない。


2013年03月18日 ChefでNode.jsを入れる [長年日記] この日を編集

_ [Ruby][Chef]ChefでNode.jsを入れる

明日職場で、banyanさん主催のChef入門用の勉強会があるので、予習でNode.jsを入れてみたら意外と面倒だったというかはまりポイントがあったのでメモ。
環境はUbuntu 12.10デスクトップ版です。

何はともあれChefをインストール。

$ gem install chef

ディレクトリーを作る。

$ mkdir .chef
$ cd .chef
$ mkdir cookbooks

Node.js用のクックブックを落としてくる。

$ git clone git://github.com/hectcastro/chef-nodejs.git cookbooks/nodejs

設定ファイルを書く。

chef.json

{
  "run_list": [
    "recipe[nodejs]"
  ]
}

solo.rb

file_cache_path '/tmp/chef-solo'
cookbook_path ['/home/kitaitimakoto/chef/cookbooks']
role_path '/home/kitaitimakoto/chef/role'
log_level :debug

では入れてみましょう。

$ sudo chef-solo -c solo.rb -j chef.json && notify-send OK || notify-send NG

NGって言われた……。

sudo: chef-solo: コマンドが見つかりません

sudoしたからパスが通らなくなったのか。
これでどうだろう。

$ sudo env PATH=/home/kitaitimakoto/.gem/ruby/2.0.0/bin:$PATH chef-solo -c solo.rb -j chef.json && notify-send OK || notify-send NG

また死んだ……。

$ /usr/local/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:106:in `require': cannot load such file -- rubygems/format (LoadError)

ググるとどうも、Ruby 1.9から2.0になるときにRubyGemsのディレクトリー構成が変わったからみたい。
ここで明らかになりますがRubyは2.0です。RVMとかそういうの使ってないのでシステムには2.0しか存在しません。ので自力で対処するしか無い。
取り敢えずrequire "rubygems/format"が成功すればいいんでしょ、ということで作ってやる。

$ cd ~/ruby/projects
$ bundle gem rubygems-format-dummy
$ cd rubygems-format-dummy
$ touch lib/rubygems/format.rb
$ git add lib/rubygems/format.rb
$ git commit -m 'Initial commit'
$ emacs -nw rubygems-format-dummy.gemspec
(`TODO`とあるところを適当に書き換える)
$ rake install

これでどうだろう。

$ sudo env PATH=/home/kitaitimakoto/.gem/ruby/2.0.0/bin:$PATH chef-solo -c solo.rb -j chef.json && notify-send OK || notify-send NG

また……。

(略)
[2013-03-19T05:01:51+09:00] FATAL: Chef::Exceptions::CookbookNotFound: Cookbook build-essential not found. If you're loading build-essential from another cookbook, make sure you configure the dependency in your metadata

「build-essential」とやらが無い、確かにそんなこと書いてあった気がする。

$ head cookbooks/nodejs/recipes/default.rb
include_recipe "build-essential"

node_packages = value_for_platform(
  [ "debian", "ubuntu" ]                      => { "default" => [ "libssl-dev" ] },
  [ "amazon", "centos", "fedora", "centos" ]  => { "default" => [ "openssl-devel" ] },
  "default"   => [ "libssl-dev" ]
)

node_packages.each do |node_package|
  package node_package do

一行目にありますね。
ダウンロードしましょう。

$ git clone git://github.com/opscode-cookbooks/build-essential.git cookbooks/build-essential

今度こそ。

$ chef-solo -c solo.rb -j chef.json && notify-send OK || notify-send NG

OK頂きました!

$ node -v
v0.8.12
$ npm -v
1.1.63

これでやっと寝られるぜ。
とその前に取り敢えずこの辺は入れておくか。

$ sudo npm install -g coffee-script less uglify-js replace grunt

2013年02月09日 Cのポインターのインクリメント [長年日記] この日を編集

_ [C]Cのポインターのインクリメント

故あってNginxモジュールのソースコードを読んでいて、Cの構造体の.->の使い分けが分からなかったので、『苦しんで覚えるC言語』でおさらいしていた。
するとポインター変数をインクリメントするというサンプルが出てきました。


    int *data;
    int average = 0,array[10] = {15,78,98,15,98,85,17,35,42,15};
    
    for (data = array;data != &array[10];data++) {  /* ここに注目 */
        average += *data;
    }

これ、インクリメント演算子++は普通整数の変数の中身を一つ増やすために使うのに、ここではその型のサイズ分増えるので、やばいなー誤読しそうだなーとツイートしていたらアンチポップさんが教えてくれました。

最初ぴんとこなかったのだけど、よくよく考えてみるとなるほど! と思った。

普段、カウンターなんかの変数をインクリメントしてi++とする時には、それは整数型の変数なので、整数のサイズ分、インクリメントしているのだ。
だから、ポインター型の変数dataをインクリメントしてdata++とする時にも、この++に「整数一つ分のサイズ」の意味があるので、自然なことなのだ。

と、「理解」したのでした。
こうして書き出してみても「整数型の変数なので、整数のサイズ分、インクリメントしている」とかって何を言っているのか意味不明なのだけどその時にはなるほど! と思ったのでした。

後日紹介してもらった資料を見て、上の「閃き」は意味不明であることがよおく分かりましたとさ。
(一応付記しておくと、これについてのやり取りをしている時には既に布団の中で半分寝ていました……いやもちろん、言い訳なんですけど)


2013年01月29日 bundle updateしたらRSpecがダウングレードしてびっくりした [長年日記] この日を編集

_ [Ruby][Bundler]bundle updateしたらRSpecがダウングレードしてびっくりした

Gitpusherに送っていたプルリクエストを取り込んでもらって、少しオウナーのmizzyさんとIRCで話していたのだけど、プルリクエストをリクエストした時には成功していたはずのテストが、今は何故か失敗する。
それも、存在しない RSpecの メソッドを呼んでいるだとかのよく分からない理由で失敗する。

その時は、仕事中で、あまり時間を掛けるわけにはいかないのでペンディングにして、帰ってから調べたのだけど、家では成功するので参った。

ただ、最初に失敗した時から当たりをつけていたのはRSpecのバージョン、だって存在しないメソッドを呼んでいるってことは、RSpecが変化したってことだよね。というわけで家の環境で調べてみた。

$ be gem list
(略)
rspec (2.11.0)

bebundle execのエイリアス)

職場で気にしていただけあって、失敗した時のバージョンも覚えていた。2.0.1だった。

あれ? また非互換を入れながらアップグレードしやがって、とか思っていたのだけど、下がっている? あれ?
というところに至ってようやく、以前にも同じことがあったのを思い出した。Bundlerって依存gemをインストールするに当たって、まず各gemの依存関係のグラフを作るのだけど、あるgemが古いバージョンの別のgemに依存していて、その古いgemは、別のgemからバージョン指定なしで依存されている時に既にその依存関係は解決されたものと見做されて新しいバージョンが入らない、ということがあるのだ。と言っても全く分からないと思うので具体的に今回のGitpusherのことで書くと、

  1. GitpusherはGrit(バージョン指定なし)に依存している
  2. Grit最新版(2.5.0)はDiff::LCS(バージョン ~> 1.1)に依存している(1.1.3が入る)
  3. Diff::LCSはRSpec(バージョン ~> 2.0)に依存している(2.0.1が入る)
  4. GitpusherはRSpec(バージョン指定なし)に依存している。RSpecは2.0.1が既に入っている

ということで、RSpec 2.0.1を使ってテストを走らせていたことになる。実際、再度bundle updateすると、RSpec 2.0.1が入る。先述の通り昔は2.11.0で走らせていたので、Bundlerが作る依存関係グラフが変わってしまったのだろう(この辺は追い掛けてないのだけど、(Bundlerが使っているであろう)RubyGemsの依存グラフを作るところが変化したのではないかと疑っている。けど、繰り返すけど調べていないので、憶測です)。

さてどこを直すべきか、というと、そりゃ、対応していないバージョンも受け入れてしまっているGitpusherを直すべきなので、テストがちゃんと動くバージョンを調べて再度プルリクエストをリクエストしましたとさ。

余談だけど、これは誇張なしにまじで、プルリクエストを送った五秒後にマージされてびびった。夜中なのに……。

本日のツッコミ(全2件) [ツッコミを入れる]

_ longchamp pliage [I agree! For Ferrari recognized headphones, they look grea..]

_ baidu [Baidu http://www.baidu.com baidu http://www.baidu.com]