Monthly Archives: 5月 2014

[メモ] MacのパッケージマネージャHomebrewのインストール

Pocket

Homebrewとは、Macのパッケージマネージメントツールで、UNIX系ソフトウェアのインストールを管理してくれるもの。
Rubyで作られている。

インストールは
http://brew.sh/index_ja.html
ここの手順に沿う。

インストール

githubからダウンロード、インストールする。
http://brew.sh/index_ja.htmlの下の方にあるコマンドをそのまま実行すればよい。
以下が実行例。

$ which ruby
/usr/bin/ruby
$ ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
==> This script will install:
/usr/local/bin/brew
/usr/local/Library/...
/usr/local/share/man/man1/brew.1

Press RETURN to continue or any other key to abort
==> /usr/bin/sudo /bin/mkdir /usr/local
(略)
From https://github.com/Homebrew/homebrew
 * [new branch]      master     -> origin/master
HEAD is now at 17eceb1 pdf2htmlex: upstream patch to fix build with latest poppler
==> Installation successful!
==> Next steps
Run `brew doctor` before you install anything
Run `brew help` to get started
$

まずbrew doctorをせい、ということなので。

$ brew doctor
Your system is ready to brew.

以上はうまくいった場合。
少しでも気を抜くとこんな風に怒られる。
24時間updateしてないだけで。
brewで作業するならまずbrew updateしてから、にしたほうが良さそう。

$ brew doctor
Warning: Your Homebrew is outdated.
You haven't updated for at least 24 hours, this is a long time in brewland!
To update Homebrew, run `brew update`.

update。

$ brew update
Updated Homebrew from 17eceb1a to 8510ebcd.
==> New Formulae
aces_container		   libltc	
(略)

PATHの変更

せっかくbrewでソフトウェアをインストールするなら、それを使ってくれるようPATHを修正する。
profileに以下の一行を加える。

$ vi ~/.bash_profile

export PATH=/usr/local/bin:$PATH

試してみよう
ドット「 . 」に続けてprofileを指定すれば読み込んでくれる。
そのあとにPATHの中身を確認。

$ . ~/.bash_profile
$
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

/usr/local/binが二回続けて出てくるけど、まあよしとする。

使い方

使い方は以下のとおり。
まあ、一般的ですよね。

  brew [info | home | options ] [FORMULA...]
  brew install FORMULA...
  brew uninstall FORMULA...
  brew search [foo]
  brew list [FORMULA...]
  brew update
  brew upgrade [FORMULA...]
  brew pin/unpin [FORMULA...]

ブロック図作成ツールblockdiag(ERROR: The _imagingft C module is not installedの倒しかた)

Pocket

ブロック図作成ツールblockdiagとは、テキストファイルから以下のような図を作成してくれるツールである。

blockdiagplanejpaa

これをFreeBSD にインストールしたので経緯を示す。
環境は10.0-RELEASE-p3、blockdiag-1.3.3である。

必要なもの

lockdiagはpkgに用意されているものの、残念ながら一発インストールというわけにはいかない。
理由は後述。
pkg以外に必要なものは以下の通り。

①ports(portsでインストールが必要なソフトウェアがある)
②日本語フォント(これはpkgでインストールしてよい)

blockdiagのインストール

一部ソフトウェアのportsからのインストールが必要だが、まずはblockdiagをpkgでインストールをしてしまったほうが楽。
依存とかあるからね。

$ pkg search blockdiag
py27-blockdiag-1.3.3

インストールしたあとに依存を調べてみると以下の通り。

$ pkg info -d py27-blockdiag-1.3.3
py27-blockdiag-1.3.3:
        py27-reportlab-3.0_1
        python27-2.7.6_4
        py27-webcolors-1.4
        py27-pillow-2.3.0_2
        py27-setuptools27-2.0.1
        py27-funcparserlib-0.3.6_1

日本語フォントのインストール

お好みで。
私はVLゴシックを。

$ pkg info|grep ja-font
ja-font-vlgothic-20130607      VLGothic Japanese TrueType fonts

さてここからが本題である。

blockdiagの罠: 吊るしのpkgでは日本語フォントを使えない

2014/5/24現在、blockdiagをpkgでインストールした場合、日本語フォントを扱うことができない。
厳密にいえば、TrueTypeフォントを使えない。
日本語を表示させようとすると、以下のように断られてしまう。

$ blockdiag ./sample.txt
ERROR: The _imagingft C module is not installed

原因は、FreeBSDにおいて言えばpy27-pillowのせい。

blockdiagが画像を生成する際にはPIL(Python Image Library)を使う。
blockdiagが依存しているpy27-pillowがそれ。
しかしデフォルト設定では、py27-pillowのTrueTypeフォント対応が無効になってるんである。

対応策: py27-pillowだけportsからインストール

ということでpy27-pillowだけportsからインストールする。
/usr/ports/graphics/py-pillowにおいてOption設定を変える。

[vanilla@yaryka /usr/ports/graphics/py-pillow]$ sudo make config
  ┌───────── py27-pillow-2.3.0_2 ─────
  │ ┌─────────────────────────
  │ │ [x] FREETYPE  TrueType font rendering support   
  │ │ [x] JPEG      JPEG image format support         
  │ │ [ ] LCMS      Little Color Management System    
  │ │ [x] PNG       PNG image format support          
  │ │ [ ] TIFF      TIFF image format support         
  │ │ [ ] WEBP      WebP image format support         
  │ └─────────────────────────
  ├──────────────────────────
  │               <  OK  >                     
  └──────────────────────────

FREETYPEのところにチェックを入れる。
/var/db/ports/graphics_py-pillow/optionsの中身がこうなってればOK.

$ cat /var/db/ports/graphics_py-pillow/options
# This file is auto-generated by 'make config'.
# Options for py27-pillow-2.3.0_2
_OPTIONS_READ=py27-pillow-2.3.0_2
_FILE_COMPLETE_OPTIONS_LIST=FREETYPE JPEG LCMS PNG TIFF WEBP
OPTIONS_FILE_SET+=FREETYPE
OPTIONS_FILE_SET+=JPEG
OPTIONS_FILE_UNSET+=LCMS
OPTIONS_FILE_SET+=PNG
OPTIONS_FILE_UNSET+=TIFF
OPTIONS_FILE_UNSET+=WEBP

そしたらpkgのpy27-pillowをいったんアンインストール。
依存があるから強制オプションを付ける。

$ sudo pkg remove -fy py27-pillow-2.3.0_2
pkg: You are trying to delete package(s) which has dependencies that are still required:
graphics/py-pillow: print/py-reportlab, graphics/py-seqdiag, graphics/py-blockdiag
... delete these packages anyway in forced mode
Deinstallation has been requested for the following 1 packages:

        py27-pillow-2.3.0_2

The deinstallation will free 2 MB
[1/1] Deleting py27-pillow-2.3.0_2...
py27-pillow-2.3.0_2 is required by: py27-reportlab-3.0_1 py27-seqdiag-0.9.0 py27-blockdiag-1.3.3, deleting anyway
 done
$

そうしたらportsからpy27-pillowをインストール

[vanilla@yaryka /usr/ports/graphics/py-pillow]$ sudo make install
===>  Installing for py27-pillow-2.3.0_2
===>   py27-pillow-2.3.0_2 depends on package: py27-setuptools27>0 - found
===>   py27-pillow-2.3.0_2 depends on file: /usr/local/bin/python2.7 - found
===>   py27-pillow-2.3.0_2 depends on shared library: libfreetype.so - found
===>   py27-pillow-2.3.0_2 depends on shared library: libjpeg.so - found
===>  Checking if graphics/py-pillow already installed
===>   Registering installation for py27-pillow-2.3.0_2
Installing py27-pillow-2.3.0_2... done
[vanilla@yaryka /usr/ports/graphics/py-pillow]$ sudo make clean
===>  Cleaning for py27-pillow-2.3.0_2
[vanilla@yaryka /usr/ports/graphics/py-pillow]$

 

テスト

詳しい記述方法は公式サイトを。
http://blockdiag.com/ja/index.html

テキストファイルに以下のような記述をする。
sample.txtとする。

blockdiag {
   春 -> 夏 -> 秋 -> 冬;
   A -> E -> F -> G;
}

あとはblockdiagに食わせるだけ。

$ blockdiag sample.txt
$

エラーもなくできた。
そしてできるファイルは以下のようなもの。
blockdiagplanejp

カクカクなのがいやなら、-aをオプションに与えればよい。

$ blockdiag -a ./sample.txt
$

アンチエイリアスがかかる。
blockdiagplanejpaa

以上。


Pythonベースのプロジェクト管理ツール、tracのインストール

Pocket

Pythonベースのプロジェクト管理ツールtracをインストールした経緯を示す。
プロジェうと管理ツールとしては、redmineもインストールしたのだが、それと比較したい。
だからひとまずインストールするだけ。
FreeBSD 10.0-RELEASEにtrac-1.0.1。

全体のながれ

  1. tracのインストール
  2. 環境作成
  3. 環境のテスト
  4. 認証用パスワードファイルの作成
  5. 起動設定
  6. 複数プロジェクト設定

インストール

tracはpkgにもあるので、特に障害もなくインストール完了。
/usr/local/lib/python2.7/site-packages/tracにドバっとファイルが作られる。

古い(といってもそこまで古くないが)ブログによると、日本語環境で使うためにいろいろと苦労が必要なようだが、現時点においてはpkg install trac一発で完了。
依存関係はこんな感じ。

$ sudo pkg info -d trac
trac-1.0.1_2:
        silvercity-0.9.7
        py27-pygments-1.6_2
        py27-Genshi-0.7_1
        py27-docutils-0.11
        python27-2.7.6_4
        python2-2_2
        py27-subversion-1.8.8_2
        py27-setuptools27-2.0.1
        py27-pytz-2014.1.1,1
        py27-Babel-1.3_1
        py27-sqlite3-2.7.6_3

データベースはご覧の通りsqliteが使われる。もちろんMySQLなど他のソフトウェアも使える。
webサーバも不要。こちらもapacheなど他のソフトウェアを使える。

設定

大したことはない。
まず環境を作る。
ディレクトリを決めておいて、そこでtracコマンドを実行し、初期化する。
例えば/usr/local/wwwの下に、tracというディレクトリを作る。
そこでtrac initenvと叩く。
注意点は、ディレクトリの文字コード。ASCIIじゃないとダメ。
また、作成したあとには、ユーザ、グループ権限を変えること。
www:wwwで動かすならそのようにchownしておく。

以下は実行例。
データベースにsqliteを使うならリターンキーを連打するだけでよい。
(プロジェクト名はMy Projectになるけど。)

example01 /usr/local/www >trac-admin /usr/local/www/trac initenv
Creating a new Trac environment at /usr/local/www/trac

Trac will first ask a few questions about your environment
in order to initialize and prepare the project database.

 Please enter the name of your project.
 This name will be used in page titles and descriptions.

Project Name [My Project]>

 Please specify the connection string for the database to use.
 By default, a local SQLite database is created in the environment
 directory. It is also possible to use an already existing
 PostgreSQL database (check the Trac documentation for the exact
 connection string syntax).

Database connection string [sqlite:db/trac.db]>

Creating and Initializing Project
 Installing default wiki pages
  CamelCase imported from 
(略)
Project environment for 'My Project' created.

You may now configure the environment by editing the file:
  /usr/local/www/trac/conf/trac.ini

If you'd like to take this new project environment for a test drive,
try running the Trac standalone web server `tracd`:
  tracd --port 8000 /usr/local/www/trac

Then point your browser to http://localhost:8000/trac.
There you can also browse the documentation for your installed
version of Trac, including information on further setup (such as
deploying Trac to a real web server).

The latest documentation can also always be found on the project
website:
  http://trac.edgewall.org/

Congratulations!
example01 /usr/local/www >

詳細な設定はtrac.iniでできるよ、とメッセージがあるが、そんなのは後回しにして、まずは起動確認。

試運転

初期設定完了時のメッセージにある通り、tracdとしてwebサーバを起動することができる。
–portにポート番号、それにディレクトリを引数に与える。

example01 /usr/local/www >tracd --port 8000 /usr/local/www/trac/
 Server starting in PID 2351.
 Serving on 0.0.0.0:8000 view at http://127.0.0.1:8000/
 Using HTTP/1.1 protocol version
 192.168.100.106 - - [17/May/2014 00:35:57] "GET / HTTP/1.1" 200 -
 192.168.100.106 - - [17/May/2014 00:35:58] "GET /favicon.ico HTTP/1.1" 404 -
 192.168.100.106 - - [17/May/2014 00:35:58] "GET /favicon.ico HTTP/1.1" 404 -
 192.168.100.106 - - [17/May/2014 00:36:00] "GET /trac HTTP/1.1" 200 -
 192.168.100.106 - - [17/May/2014 00:36:00] "GET /trac/chrome/common/css/wiki.css HTTP/1.1" 200 - 1

この状態で、ブラウザから接続して、以下のような表示があれば成功。
さっき作ったMy Projectが見えていますね。
tractestboot01
ただ、この状態では何もできない。
tractestboot02
メニューのログインをクリックしても、ページがない旨のエラーが表示されるはず。
まずは認証の準備をする必要がある。
ターミナルに戻ってCtrl+Cで抜けよう。

認証用のパスワードファイル作成

認証の準備すなわちパスワードファイルの作成である。
パスワードファイルだから、平文で書かれていてはまずい。
ではどうやって作るか。
apacheをインストールしていれば、htpasswdを使う。
apacheがなければ。
インストールドキュメントに書いてあるスクリプトを使う。
http://emelfm2.net/wiki/TracStandalone

ちょっと横道に逸れるが。
いずれにしても、このさきtracにユーザを追加する場合には、ここで作成したパスワードファイルへの登録で行う。
これを面倒と感じるかどうか。

さておき、以下を適当な名前で、たとえばtrac-digest.pyとして保存する。

from optparse import OptionParser
# The md5 module is deprecated in Python 2.5
try:
    from hashlib import md5
except ImportError:
    from md5 import md5
realm = 'trac'

# build the options
usage = "usage: %prog [options]"
parser = OptionParser(usage=usage)
parser.add_option("-u", "--username",action="store", dest="username", type = "string",
                  help="the username for whom to generate a password")
parser.add_option("-p", "--password",action="store", dest="password", type = "string",
                  help="the password to use")
parser.add_option("-r", "--realm",action="store", dest="realm", type = "string",
                  help="the realm in which to create the digest")
(options, args) = parser.parse_args()

# check options
if (options.username is None) or (options.password is None):
   parser.error("You must supply both the username and password")
if (options.realm is not None):
   realm = options.realm
   
# Generate the string to enter into the htdigest file
kd = lambda x: md5(':'.join(x)).hexdigest()
print ':'.join((options.username, realm, kd([options.username, realm, options.password])))

使い方は以下の通りで、python trac-digest.pyに続けて、-u <ユーザネーム> -p <パスワード>とし、その出力をファイルに向ける。

example01 /usr/local/www > python trac-digest.py -u username -p password >> /tmp/digest.txt

つまりユーザusernameを、passwordというパスワードで作成している。

生成されたファイルの中身は以下の通り。
2カラムめはrealm。

username:trac:a053da77aad45fc9d4a506ef6fd

 

本格起動

今度はtracdにオプションを特盛で与える。
–authで先ほどのパスワードファイルを与える。
その際には、プロジェクトのベースディレクトリ、パスワードファイル、realmを指定する。
ベースディレクトリとは、もし環境を作ったディレクトリが/usr/local/www/tracならtracになる。
このベースディレクトリは、のちにwebサーバを動かしたとき、http://<サーバアドレス>/<ベースディレクトリ>というように使われる。

最終的に–authは、本記事の例でいえば、–auth=trac,/tmp/digest.txt,tracとなる。

さらに、-pで待ち受けポート、–user, –groupでtracdを動かす権限を、-dでdaemoniseを指定する。
以下のようになる。

# tracd --auth=trac,/tmp/digest.txt,trac -p 8000 --user=www --group=www /usr/local/www/trac/ -d

試運転の時とは違い、すぐにプロンプトが戻ってくる。
試しにsockstatを見てみると、以下の通り。

# sockstat -l4
 USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
 www python2.7 6517 3 tcp4 192.168.100.240:8000 *:*

 

認証の確認

さきほどはクリックしてもページのなかった「ログイン」が、今度はIDとパスワードを訊いてくるようになっているはず。
tractestboot03
tractestboot04
これでチケットの発行ができる。

管理者権限の作成

しかしユーザusernameは一般ユーザである。
彼に管理者権限を与えるには、以下のようにtracコマンドで操作を行う。

example01 /usr/local/www >trac-admin /usr/local/www/trac permission add username TRAC_ADMIN
example01 /usr/local/www >

このあと、ユーザusernameには管理者メニューが現れる。
tractestboot05

なお、管理者であれば、他ユーザの権限も操作できる。
tractestboot06
したがって、管理者権限を与えるのは最初の一人だけ、にすることもできる。

注意点としては、各ユーザの権限はさきほど作成したパスワードファイルでは管理されていない、ということ。

繰り返すが、ユーザの登録はパスワードファイルへの登録で、(少なくとも初回の)権限変更は上記コマンドで、という仕組みをどう感じるか。
まあちょっと面倒くさいかもしれませんな。

システム起動時設定(シングル環境モード)

以上でtracをとりあえず起動する設定は済んだ。
あとはシステム起動時にtracが起動するよう、/etc/rc.confに設定を加える。
/usr/local/etc/rc.d/trac内のコメントに沿ってrc.confに追加する。
以下は例。## trac

tracd_enable="YES"
tracd_listen="192.168.100.240"
tracd_port="8000"
tracd_envdir="/usr/local/www/"
tracd_env="trac"
tracd_args="--user=www --group=www --auth=trac,/tmp/digest.txt,trac"

tracd_envdirとtracd_envに注意。
こういう書き方をしてtracに接続するといきなりMy Projectに移動する。
プロジェクトが一つであれば何の問題もないが、複数プロジェクトを抱えたい場合には困る。

複数プロジェクトの運営

複数プロジェクトを登録したいのであれば、必要なぶんだけディレクトリを作り、そこでtrac-admin initenvすればよい。
例えば/usr/local/www/tracsなんてディレクトリを作り、projecttemp, projectaltというディレクトリをさらに作る。
それぞれにinit-envで環境を作る。
このとき、/etc/rc.confはこのようにする。
tracd_envに/usr/local/www/tracsを指定し、tracd_envはコメントアウト。
–authで指定するベースディレクトリにアスタリスクを与えれば、パスワードファイルを複数のプロジェクトで共有できる。

## trac
tracd_enable="YES"
tracd_listen="192.168.100.240"
tracd_port="8000"
tracd_envdir="/usr/local/www/tracs"
#tracd_env=""
tracd_args="--user=www --group=www --auth=*,/tmp/digest.txt,trac"

こんな感じ。
tractestboot07
tractestboot08

以上

FreeBSDにredmineのインストール(取りあえず立ち上げるとこまで)

Pocket

Rubyで作られたプロジェクト管理システムRedmineを、FreeBSDにインストールした。
文字通り、インストールだけ。
というのもインストールだけで大変だから。
その経緯を示す。

前提

インストールしたのはredmine-2.5.1。
基本、公式の以下手順に沿うが、FreeBSD特有の条件で異なる手順を採ることもある。
http://www.redmine.org/projects/redmine/wiki/RedmineInstall
また、redmineはそのデータ格納にデータベースソフトウェアが必要で、sqlite3を使っている。
複数ユーザで使うならMySQLやPostgreSQLを推奨、というのが公式見解。
同様にwebサーバもapacheやnginxが推奨されているが、ここではwebrickでテストするところまで。

redmineのインストール

pkgからインストール。
pkg install redmineでよい。
apacheなどのwebサーバはなくてもよいが、なぜかgtk2も付いてくるのが謎だが、jailに入れるからもう気にしない。

# pkg install redmine
(略)
       Installing cups-image: 1.7.2
        Installing gtk-update-icon-cache: 2.24.22
        Installing ghostscript9: 9.06_6
        Installing gtk2: 2.24.22_3
        Installing gtk-engines2: 2.20.2_2
        Installing librsvg2: 2.36.4_1
        Installing ImageMagick: 6.8.0.7_8,1
        Installing rubygem-rmagick: 2.13.2
        Installing redmine: 2.5.1_2

The installation will require 651 MB more space

122 MB to be downloaded

Proceed with installing packages [y/N]: y

/usr/local/www/redmineにインストールされる。
ユーザ/グループはwwwが使われる。

空のデータベースを作る

SQLite3を使っているなら不要

redmineでデータベースに繋ぐ設定をする

/usr/local/www/redmine/configの下に各種設定ファイルがある。
ここでデータベースの設定を行う。
database.yml.exampleをdatabase.ymlとしてコピーし、書き換える。

/usr/local/www/redmine/config # cp ./database.yml.example ./database.yml
/usr/local/www/redmine/config #

「production」から始まる塊を以下のように。

#production:
  #adapter: mysql2
  #database: redmine
  #host: localhost
  #username: root
  #password: ""
  #encoding: utf8

production:
  adapter: sqlite3
  database: db/redmine.sqlite3

つまり、mysql2を使うような設定を、sqlite3に変えているわけですな。

bundler他のインストール

公式ドキュメントによればここでbundlerなどのインストールを行うが、FreeBSDでpkg/portsからインストールした場合にはスキップ可。
ご覧の通りredmineがインストールされた状態でbundlerもインストールされている。

$ pkg info|grep bundler
rubygem-bundler-1.5.3          A tool that manages gem dependencies for ruby applications

セッションストア秘密鍵の作成

クッキーの生成に使用される秘密鍵を作る。

# rake generate_secret_token
(in /usr/local/www/redmine)
#

データベースのスキーマ(テーブル)作成

テーブル作成
環境変数を使うのでshで。

# sh
# RAILS_ENV=production rake db:migrate
(略)
==  StoreRelationTypeInJournalDetails: migrating ==============================
==  StoreRelationTypeInJournalDetails: migrated (0.0057s) =====================

==  DeleteOrphanTimeEntriesCustomValues: migrating ============================
==  DeleteOrphanTimeEntriesCustomValues: migrated (0.0009s) ===================

==  ChangeChangesetsCommentsLimit: migrating ==================================
==  ChangeChangesetsCommentsLimit: migrated (0.0000s) =========================

#

データベースにデフォルトデータを投入

作ったばかりのテーブルにデータ(default configuration data)を投入

# RAILS_ENV=production REDMINE_LANG=ja rake redmine:load_default_data
(in /usr/local/www/redmine)
Default configuration data loaded.
#

パーミッション設定

あと少し。
redmineがファイルを置くディレクトリのパーミッションを設定する。
FreeBSDにおいてはユーザ、グループにwww:wwwを使う。

# mkdir -p tmp tmp/pdf public/plugin_assets

# chown -R www:www files log tmp public/plugin_assets
# chmod -R 755 files log tmp public/plugin_assets
#

これでほぼ準備完了

試運転

webrickでredmineを起動し、動くかどうかを確かめる。

# ruby script/rails server webrick -e production
=> Booting WEBrick
=> Rails 3.2.17 application starting in production on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2014-05-11 11:43:43] INFO  WEBrick 1.3.1
[2014-05-11 11:43:43] INFO  ruby 1.9.3 (2013-11-22) [amd64-freebsd10]
[2014-05-11 11:43:43] INFO  WEBrick::HTTPServer#start: pid=4187 port=3000

ご覧の通り、redmineをインストールしたマシンのポート3000で待ち受け。
ブラウザで繋ぐと、ターミナルには例えば以下のような反応があるはず。

Started GET "/" for 192.168.1.106 at 2014-05-11 11:44:01 +0900
Processing by WelcomeController#index as HTML
  Current user: anonymous
  Rendered welcome/index.html.erb within layouts/base (379.0ms)
Completed 200 OK in 716.5ms (Views: 468.3ms | ActiveRecord: 20.8ms)

あとはブラウザから操作。

最初のログイン

以下のような画面が表示されれば成功で、さっそく右上のログインをクリック

redminelogin

ID、パスワードはadmin,admin

reminefirstlogin

以下の画面に遷移

redmineafterlogin

ためしに「管理」をクリックすると、以下の画面に。

redminemanagement

以上。

PyInstallerで作ったWindowsアプリでバージョンを表示させたい(Version Resource Fileの作りかた)

Pocket

Windowsアプリケーションのバージョンは、そのプロパティから確認できる。
PyInstallerでWindowsアプリケーションを作るときにも、ぜひここに登録をしたい。

PyInstallerでは、あらかじめ用意しておいたVersion Resource Fileを読み込ませることで、バージョンなどの情報をアプリケーションに書き込むことができる。

しかし、その方法はちょっとトリッキーなので、ここにその方法を採録する。
トリッキーな内容は何かというと。
要するにVersion Resourceをスクラッチで書くのは大変なので、そのへんにあるWindowsアプリケーション(厳密には拡張子が.exeの実行ファイル)から抜き出してきてそれを使い回すというもの。
れっきとした公式手順である。
したがって全体の流れは以下のようになる。

全体の流れ

1.「既存の」WindowsアプリケーションからVersion Resourceを抜き出す。
2.抜き出したファイルを書き換え。
3.そのファイルを指定してPyInstallerを実行

Version Resourceファイルの抜き出し

PyInstallerには、pyi-grab_version.pyというスクリプトが含まれている。
PyInstallerを展開してできるutilsディレクトリの下にある。
お使いのWindows上にある実行ファイルを引数に与えてpy-grab_version.pyを実行すればよい。
結果はpy-grab_version.pyと同じディレクトリにfile_version_info.txtとして書き込まれる。

以下はWindows 7のcmd.exeを引数に与えた場合の実行例である。

C:\home\py\PyInstaller-2.1\utils>python grab_version.py "C:\Windows\winsxs\x86_microsoft-windows-commandprompt_31bf3856ad364e35_6.1.7600.16385_none_8ae31ce07bb01ee0\cmd.exe"
Version info written to: C:\home\py\PyInstaller-2.1\utils\file_version_info.txt

C:\home\py\PyInstaller-2.1\utils>

以下が書き出されたfile_version_info.txt。
UTF-8なので注意。

# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
  ffi=FixedFileInfo(
    # filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
    # Set not needed items to zero 0.
    filevers=(6, 1, 7600, 16385),
    prodvers=(6, 1, 7600, 16385),
    # Contains a bitmask that specifies the valid bits 'flags'r
    mask=0x3f,
    # Contains a bitmask that specifies the Boolean attributes of the file.
    flags=0x0,
    # The operating system for which this file was designed.
    # 0x4 - NT and there is no need to change it.
    OS=0x40004,
    # The general type of file.
    # 0x1 - the file is an application.
    fileType=0x1,
    # The function of the file.
    # 0x0 - the function is not defined for this fileType
    subtype=0x0,
    # Creation date and time stamp.
    date=(0, 0)
    ),
  kids=[
    StringFileInfo(
      [
      StringTable(
        u'040904B0',
        [StringStruct(u'CompanyName', u'Microsoft Corporation'),
        StringStruct(u'FileDescription', u'Windows Command Processor'),
        StringStruct(u'FileVersion', u'6.1.7600.16385 (win7_rtm.090713-1255)'),
        StringStruct(u'InternalName', u'cmd'),
        StringStruct(u'LegalCopyright', u'© Microsoft Corporation. All rights reserved.'),
        StringStruct(u'OriginalFilename', u'Cmd.Exe'),
        StringStruct(u'ProductName', u'Microsoft® Windows® Operating System'),
        StringStruct(u'ProductVersion', u'6.1.7600.16385')])
      ]), 
    VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
  ]
)

次は本ファイルを書き換える。

ファイルの書き換え

cmd.exeのプロパティ->詳細タブと見比べながら書き換えていけばよい。
それ以外は触らないこと。
cmdexeproperty
たとえばこんな感じ。

# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
  ffi=FixedFileInfo(
    # filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
    # Set not needed items to zero 0.
    filevers=(1, 0, 0, 0),
    prodvers=(1, 0, 0, 0),
    # Contains a bitmask that specifies the valid bits 'flags'r
    mask=0x3f,
    # Contains a bitmask that specifies the Boolean attributes of the file.
    flags=0x0,
    # The operating system for which this file was designed.
    # 0x4 - NT and there is no need to change it.
    OS=0x40004,
    # The general type of file.
    # 0x1 - the file is an application.
    fileType=0x1,
    # The function of the file.
    # 0x0 - the function is not defined for this fileType
    subtype=0x0,
    # Creation date and time stamp.
    date=(0, 0)
    ),
  kids=[
    StringFileInfo(
      [
      StringTable(
        u'040904B0',
        [StringStruct(u'CompanyName', u'hoge Corporation'),
        StringStruct(u'FileDescription', u'hoge'),
        StringStruct(u'FileVersion', u'1.0.0'),
        StringStruct(u'InternalName', u'hoge'),
        StringStruct(u'LegalCopyright', u'© hoge Corporation. All rights reserved.'),
        StringStruct(u'OriginalFilename', u'hoge.exe'),
        StringStruct(u'ProductName', u'hoge'),
        StringStruct(u'ProductVersion', u'1.0.0')])
      ]), 
    VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
  ]
)

ファイルの準備はおしまい。
あとはビルドの際にファイルを指定するだけ。

Version Resourceファイルを指定してビルド

単純に–version-file=<ファイル名>と指定するだけ。
だから実行例は省く。
pyhogeversion
無事に表示された。

補足

参考までに公式の宣言、つまりVersion Resourceは複雑すぎマジ無理、と言っている箇所を貼り付けておく。

because version resources are complex. Some elements are optional, others required. When you view the version tab of a Properties dialog, there’s no simple relationship between the data displayed and the structure of the resource. Using pyi-grab_version you can find an executable that displays the kind of information you want, copy its resource data, and modify it to suit your package.

Windowsにpyinstallerをインストール

Pocket

過日、起こしたpyinstallerのインストール方法が盛大に間違っていたので改めて示す。
(動いていたからまったく気がつかなかった・・・・)
PythonでWindowsアプリケーションを作ってみよう

pyinstallerとは、pythonプログラムをWindowsなどで動く実行ファイルに変換してくれるものだ。
自作pythonプログラムを他人にも使ってもらおうとすると、当然その人もpythonをインストールすることが前提になる。
しかしスタンドアロンの実行ファイルにできるなら、そんな面倒を解消できる。
ありがたいことでございます。

PyInstallerのインストール

公式のドキュメントに沿いつつ進める。
インストール先はWindows。

前提

Pythonはもちろんインストールしてあるとして、以下のものが必要
・PyWin32
・(場合によって)setuptools/distribute

補足

2014/5/2現在、ActivePythonのPyPMにPyInstallerはありません。

PyWin32のインストール

PyWin32はPythonからWindows APIにアクセスするためのもの。
以下から対応するバージョンをダウンロードし、インストールする。
http://sourceforge.net/projects/pywin32/files/?source=navbar
32bit WindowsにPython2.7をインストールしているなら、pywin32-218.win32-py2.7.exeをダウンロード(218はバージョンナンバなので変わる)。
py3201
py3202
pipがインストールされているなら、この時点でpip install PyInstallerでOK。

setuptools/distributeのインストール

pipがインストールされているならこのステップは不要。
また、setuptools, distributeどっちでもよい。
2014/5/2現在、setuptoolsでいいようだが、私がインストールしたのはdistribute。
https://pypi.python.org/pypi/distribute/0.7.3

ダウンロードして、伸張して、できたディレクトリでpython setup.py install。
distribute, setuptoolsの違いについては以下を。
http://stackoverflow.com/questions/6344076/differences-between-distribute-distutils-setuptools-and-distutils2

PyInstallerのインストール

以下から最新のPyInstallerをダウンロード。
https://pypi.python.org/pypi/PyInstaller/
伸張して、できたディレクトリでpython setup.py install。

C:\local\pyinstaller>python setup.py install
(略)
Installed c:\python27\lib\site-packages\pyinstaller-2.1-py2.7.egg
Processing dependencies for PyInstaller==2.1
Searching for distribute==0.6.19
Best match: distribute 0.6.19
Adding distribute 0.6.19 to easy-install.pth file
Installing easy_install-script.py script to C:\Python27\Scripts
Installing easy_install.exe script to C:\Python27\Scripts
Installing easy_install-2.7-script.py script to C:\Python27\Scripts
Installing easy_install-2.7.exe script to C:\Python27\Scripts

Using c:\python27\lib\site-packages
Finished processing dependencies for PyInstaller==2.1

C:\local\pyinstaller>

コマンドプロンプトを開いてpyinstaller –versionと叩いてみる。
うまく行っているならパスも通っている。

C:\local>pyinstaller --version
2.1

C:\local>

[Python2] Hex文字列とBin文字列でコンバート

Pocket

メモでござる。

Hex文字列をBin文字列に変換したり、その逆に変換するには。

Bin->Hex

まずサンプル。

bindata = "00001011"
hexdata = ""
scale = 2
num_of_digits = 2

hexdata = hex(int(bindata,scale))[2:].zfill(num_of_digits)

print "%s ====> %s" % (bindata, hexdata)

実行例。

00001011 ====> 0b

 

説明

まずint()で数値に変換する。
その際には第二引数で基数を与える。bin文字列なら2を。hexなら16を与える。
次にその数値をhex()で16進数に変換。
そのままだと頭に0xが付いてしまうので[2:]として取り除く。
さらにzfillで桁数分0で埋める。

Hex->Bin

bindata = ""
hexdata = "1c"
scale = 16
num_of_digits = 8

bindata = bin(int(hexdata,scale))[2:].zfill(num_of_digits)

print "%s ====> %s" % (hexdata, bindata)

実行例

1c ====> 00011100