harry’s memorandum

おれおれメモ

TWINBIRD サイクロンスティック型クリーナー TC-E117W

TWINBIRD サイクロンスティック型クリーナー ホワイト TC-E117W というのを購入しました。
実家用にたまに使う掃除機だから3,130円の掃除機をチョイス。
2014年1月1日の朝3時ぐらいにポチって1月2日の午前中に届きました。いい時代になりましたよ。

TWINBIRD サイクロンスティック型クリーナー ホワイト TC-E117W

TWINBIRD サイクロンスティック型クリーナー ホワイト TC-E117W


組み立ては説明書はまったく必要ないぐらい簡単です。
f:id:dharry:20140102154438j:plain
f:id:dharry:20140102154440j:plain


コードレスじゃないのでコードが鬱陶しいです。ヘッドもあまり快適な動きじゃないです。
でも値段から考えると十分だと思います。吸引力はそこそこあるし、スティック型なので、隅に置いておけば邪魔にならないです。少し掃除したところ結構なゴミが。写真じゃわかりにくいけど、3000円程度にしてはよいお買い物だと思います。
f:id:dharry:20140102154434j:plain

俺的に最強のクリップボード履歴とメモツール

Windows/Office武勇伝 <Surface Proが当たる! 開発者グループOPENキャンペーン>

競馬の予想ソフトが欲しくて、VAIO PCV-T510R というやつを買ったのがWindowsとの初対面でした。Windows98は本当に脆いOSで結構泣かされました。いまはSurface Proが欲しいので自分の使っているWindowsツールを紹介します。

はたくり + EvMEMO
この2つの組み合わせが最強です。いくつか最強な理由を述べていきます。

動作が軽い

搭載メモリが32GBでも、高速SSDに換装しても、CPUがHaswellでも、やっぱり軽いアプリが一番です。はたくり+EvMEMOはWindows95で動かしても十分な軽さでした。

はたくり

f:id:dharry:20130914003143p:plain
クリップボード履歴です。viキーバインドが使えます。これは強い。履歴を "j" で移動して "yy" でヤンクや、いらない履歴を "dG" で全部消したりできます。香り屋さんのvimのバッファを使いつつ、はたくりでWindowsのクリップボードを駆使すると、もうコピーペーストだけしかしていない気分になれます。
また、はたくりは、ctrl-qで表示して、Escでタスクトレイに隠れてくれます。左手だけで完結します。

EvMEMO

f:id:dharry:20130914003152p:plain
ただのシンプルなメモツールです。これの強みはalt-zで表示して、Escでタスクトレイに隠れると同時に保存してくれるところです。*1はたくり、EvMEMO、どちらもEscで閉じることができるのは嬉しいです。



理由を色々つけましたが、結局は慣れたツールが一番ですね。

*1:設定でescで閉じるにチェックを入れる必要があります

rubyでQRコード生成

ライブラリはたくさんあって何を使えばいいのやら。いくつか試して良さそうなものを。

rqrcode

インストール

rqrcodeとrqrcode_pngは一緒にいれると便利。

 $ gem install rqrcode
 $ gem install rqrcode_png
require 'rubygems'
require 'rqrcode'
require 'rqrcode_png'

qr = RQRCode::QRCode.new('hoge', :size => 4, :level => :h )
png = qr.to_img
#png.resize(90,90).save("hoge0.png")
png.save("hoge0.png")

barby

インストール

ネーミングセンスいいですよね。QRコードだけでなく一次元コード(バーコード)も色々できたり。

require 'rubygems'
require 'barby'
require 'barby/barcode/qr_code'
require 'barby/outputter/png_outputter'

qr = Barby::QrCode.new('hoge', { :size => 4, :level => :h })
File.open('hoge1.png', 'w'){|f|
  f.write qr.to_png
}

やりたかったこと

QRコードで資産データシールを作りたいだけなんですね。

require 'rubygems'
require 'fileutils'
require 'RMagick'
require 'rqrcode'
require 'rqrcode_png'

text = "hoge"
qrimage = text + "-tmp.png"

width, height = 100, 100

qr = RQRCode::QRCode.new(text, :size => 4, :level => :h )
png = qr.to_img
png.resize(width, height).save(qrimage)

height += 20 # margin

image = Magick::Image.read(qrimage).first
image = image.change_geometry("#{width}x#{height}") do |cols,rows,img|
  img.resize!(cols, rows)
  img.background_color = 'white'
  img.extent(width, height)
end

draw = Magick::Draw.new
draw.annotate(image, 0, 0, width / 2 , 110, "id: #{text}") do
  self.fill = '#000000'
  self.align = Magick::LeftAlign
  self.stroke = 'transparent'
  self.pointsize = 10
  self.text_antialias = true
  self.kerning = 1
end
image.write(text + ".png")
FileUtils.rm(qrimage, {:force => true})

f:id:dharry:20130909002150p:plain

やっつけ感が拭いきれませんが、とりあえず目的は達成できました。時間があるときにrqrcodeやRMagickをもっと掘り下げて見たいと思います。

瞳孔が開くほど簡単にredmineを構築できる「Bitnami」 (1)

Redmineって便利だけどインストールが結構面倒じゃないですか。
特にCentOSにインストールする場合だと、rvmでrubyのバージョン指定して、passengerコンパイルして、apacheのconfいじって.....ええと正直きつい。
http://blog.redmine.jp/articles/2_3/installation_centos/

そこで「Bitnami」登場です。

BitNami Redmine Stack provides a one-click install solution for Redmine.

http://bitnami.com/stack/redmine/installer

「Bitnami Redmine」はフルスタックソリューションです。bitnami-redmine-2.3.2-1の場合は以下すべてを含んでいます。デフォルトは/opt以下にインストールします。 

本当に超楽です。CentOS6.4 と bitnami-redmine-2.3.2-1 を使ってredmine構築まで行ってみます。


インストール方法

インストーラダウンロード

まずbitnamiのサイトでインストーラをダウンロードします。
f:id:dharry:20130829005701p:plain

インストーラ実行

インストーラを実行。終わり。お疲れ様でした。

$ sudo ./bitnami-redmine-2.3.2-1-linux-x64-installer.run

インストールは簡単すぎるので、少しTIPSを備忘録として残しておきます。


monitでプロセス監視

monitはプロセスを監視するツールです。なぜかmonitはインストールされないので、DAGリポジトリなどからyumでmonitをインストールします。

$ wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.i686.rpm
$ rpm -ivh rpmforge-release-0.5.2-2.el6.rf.i686.rpm
$ yum install monit
$ ln -s /opt/redmine-2.3.2-1/config/monit/bitnami.conf /etc/monit.d/bitnami.conf
$ chkconfig --level 345 monit
$ /etc/init.d/monit start

必要に応じて/etc/monit.conf や /opt/redmine-2.3.2-1/config/monit/conf.d/*.conf を修正してください。

logrotateを設定してログの肥大を防ぐ

bitnamiにはlogrotate.confも用意されています。必要に応じてconfを修正してください。

$ ln -s /opt/redmine-2.3.2-1/config/logrotate/bitnami.conf /etc/logrotate.d/bitnami.conf

Bitnami Redmine を自動起動

Bitnami Redmineのサービス起動スクリプトは /opt/${installdir}/ctlscript.sh です。これを/etc/init.d以下にコピーします。

$ cp -p /opt/redmine-2.3.2-1/ctlscript.sh /etc/init.d/bitnami-redmine

chkconfigで自動起動の登録をするため、コピーした/etc/init.d/bitnami-redmineを少しだけ修正します。シェバン(#!/bin/sh)のあと1つ改行を入れたあと、chkconfig: と description: を追加します。この意味は 「man chkconfig」のRUNLEVEL FILESセクションを参照してください。

#!/bin/sh
#
# chkconfig: 345 80 30
# description: BitNami Redmine Service

chkconfigでサービス登録。

$ chkconfig --add bitnami-redmine

/etc/init.dにコピーしたファイル名が--add で登録する名前になります。

Redmineのサブディレクトリを変更

デフォルトのパスは http://yourhost/redmine になっています。ここでは http://yourhost/redmine => http://yourhost/bts へ変更します。
最初は、Alisasを変更します。

$ cat /opt/redmine-2.3.2-1/apps/redmine/conf/httpd-prefix.conf
#Alias /redmine/ "/opt/redmine-2.3.2-1/apps/redmine/htdocs/public/"
#Alias /redmine "/opt/redmine-2.3.2-1/apps/redmine/htdocs/public"
Alias /bts/ "/opt/redmine-2.3.2-1/apps/redmine/htdocs/public/"
Alias /bts "/opt/redmine-2.3.2-1/apps/redmine/htdocs/public"

Include "/opt/redmine-2.3.2-1/apps/redmine/conf/httpd-app.conf"

次にRAILS_RELATIVE_URL_ROOT と PassengerPreStart を変更します。

$ cat /opt/redmine-2.3.2-1/apps/redmine/conf/httpd-app.conf
<Directory "/opt/redmine-2.3.2-1/apps/redmine/htdocs/public">
    PassengerEnabled on
    Options -MultiViews
    AllowOverride All
    <IfVersion < 2.3 >
    Order allow,deny
    Allow from all
    </IfVersion>
    <IfVersion >= 2.3>
    Require all granted
    </IfVersion>
    #SetEnv RAILS_RELATIVE_URL_ROOT "/redmine"
    SetEnv RAILS_RELATIVE_URL_ROOT "/bts"
    PassengerAppRoot "/opt/redmine-2.3.2-1/apps/redmine/htdocs"
</Directory>

#PassengerPreStart http://127.0.0.1:80/redmine
PassengerPreStart http://127.0.0.1:80/bts

apacheを再起動

$ /etc/init.d/bitnami-redmine restart apache

このようなエラーが表示される場合はmonitがインストールしていない可能性があります。

which: no monit in (/opt/redmine-2.3.2-1/perl/bin:/opt/redmine-2.3.2-1/git/bin:/opt/redmine-2.3.2-1/sqlite/bin:/opt/redmine-2.3.2-1/ruby/bin:/opt/redmine-2.3.2-1/subversion/bin:/opt/redmine-2.3.2-1/php/bin:/opt/redmine-2.3.2-1/mysql/bin:/opt/redmine-2.3.2-1/apache2/bin:/opt/redmine-2.3.2-1/common/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin)

monitを動かす必要がなくてもエラーを抑止するのでインストールしておいた方が良いです。


自作PCケース BitFenix PRODIGY Black にしました

新PC買いました。自称、中学生の気持ちがわかる男なのでケースは中学生仕様。AMD派の私としてはRichland A10あたりにしたかったのですが、わけあって Haswellに妥協。


f:id:dharry:20130824113937j:plain

スペック比較

旧PC 新PC
CPU AMD Phenom X4 9550 Intel Core i5 4430
GPU/OnBoard ATI Radeon HD 4200 Intel HD Graphics 4600
MainBoard Micro-Star INTERNATIONAL 78GTM-E45 ASRock H87M-ITX

ベンチマーク - エクスペリエンスインデックス

せっかくなので旧PCと新PCをベンチマーク。まずはWindows7のエクスペリエンスインデックス。あれ?思ったより性能差がみえない...

f:id:dharry:20130827004356p:plain

f:id:dharry:20130827004403p:plain

ベンチマーク - GeekBench3

エクスペリエンスインデックスは数値がざっくりすぎるので、ここは新しいバージョンのGeekBench3で。

f:id:dharry:20130827010609p:plain
http://browser.primatelabs.com/geekbench3/31060

f:id:dharry:20130827010618p:plain
http://browser.primatelabs.com/geekbench3/31064

結論

AMD Phenom X4 9550、お前は 5年近くよく頑張ってくれたよ。」

Win32OLEでインストール済みソフトウェア一覧を取得してみたよ

リーマンは時折無駄としか思えない人力作業を強制させられるときがあります。インベントリを人力で調べるなんて拷問ですよ。
ささっとvbsを書いて終わりのつもりだったのですが妙に遅い...半端ではない遅さ。

hostname = "remote_host"
set locator = CreateObject("WbemScripting.SWbemLocator")
Set wmi = locator.ConnectServer(hostname, "ROOT\cimv2", "user", "password")
Set items = wmi.ExecQuery("Select * from Win32_Product",,48)

For Each item in items
    Wscript.Echo "Caption: " & item.Caption
    Wscript.Echo "Version: " & item.Version
Next

どうやら win32_productクラスがよくないようです。「win32_product slow」とググるとワンサカ出てきます。MSI経由で情報を取得するため、超がつくほど遅いようです。

インストール済みアプリケーションの情報取得はレジストリ経由の方が速そう。ただx86とx64のアプリケーションは別のレジストリで管理しているので注意が必要です。

require 'win32ole'
require 'socket'

module REG
  arch = ENV["PROCESSOR_ARCHITECTURE"] == "AMD64" ? x64 : "x86"
  
  UNINSTALLS = 
    if arch == "x64"
      [
        "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\uninstall",
        "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\uninstall",
      ]
    else
      [
        "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\uninstall",
      ]
    end

  HKEY_CLASSES_ROOT   = 0x80000000
  HKCR                = 0x80000000
  HKEY_CURRENT_USER   = 0x80000001
  HKCU                = 0x80000001
  HKEY_LOCAL_MACHINE  = 0x80000002
  HKLM                = 0x80000002
  HKEY_USERS          = 0x80000003
  HKEY_CURRENT_CONFIG = 0x80000005
  HKEY_DYN_DATA       = 0x80000006
end

include REG

# File activesupport/lib/active_support/core_ext/hash/keys.rb
class Hash
  def symbolize_keys!
    keys.each do |key|
      self[(key.to_sym rescue key) || key] = delete(key)
    end
    self
  end
end

class Software
  def initialize(hostname = ".", opt = {})
    wmi = conn_server(hostname, opt)
    @reg = wmi.Get("StdRegProv")
  end

  def conn_server(hostname, opt)
    locator = WIN32OLE.new("WbemScripting.SWbemLocator")
    if Socket.gethostname == hostname || "." == hostname
      locator.ConnectServer("." ,"root\\default")
    else
      locator.ConnectServer(hostname ,"root\\default", opt[:user], opt[:pass])
    end
  end
  
  def each_subkey
    in_param = @reg.Methods_("EnumKey").InParameters.SpawnInstance_()
    in_param.hDefKey = REG::HKLM
    REG::UNINSTALLS.each {|key|
      in_param.sSubKeyName = key
      out_param = @reg.ExecMethod_("EnumKey", in_param)
      out_param.sNames.each {|subkey|
        yield  key + "\\" + subkey
      }
    }
  end

  def each_products
    in_param = @reg.Methods_("GetStringValue").InParameters.SpawnInstance_()
    in_param.hDefKey = REG::HKLM
    self.each_subkey {|key|
      product = {}
      in_param.sSubKeyName = key
      %w(DisplayVersion DisplayName).each {|label|
        in_param.sValueName = label
        out_param = @reg.ExecMethod_("GetStringValue",in_param)
        product[label] = out_param.sValue.to_s 
      }
      yield product.symbolize_keys! 
    }
  end
end

こういうのはWin32OLEで書くほうが楽しいです。こんなかんじで実行すればOK.

so = Software.new
so.each_products {|h|
 next if h[:DisplayName].empty?
 p h
}