Windows標準付属ゲームのスコア履歴を記録する

スコアがどこに入っているかを調べると、%APPDATA%\Microsoft Games の下のゲーム毎のフォルダーに格納されている。
ソリテアだと、%APPDATA%\Microsoft Games\Solitaire\SolitaireSettings.xml
ゲーム名のフォルダーは、Explorerから見ると「ソリテア」と片仮名になっているが、実際にはSolitaireと英字だ。Usersと「ユーザー」のようなもの。


拡張子がxmlになっているが、xmlの前後に何か付いていて、そのままではxmlパーサーで読めない。
そこで、以前と、以降を最初に削除してやってから、パーサーに掛ける。
勝ち数、試合数、勝率をホームディレクトリの下のゲーム名のフォルダーに日付を付けて記録する。
これをタスクマネージャから毎日実行すれば良い。

require "rexml/document"

ROOT= "<Root>".encode("UTF-16LE").force_encoding("ASCII-8BIT")
TOOR="</Root>".encode("UTF-16LE").force_encoding("ASCII-8BIT")

def game(name, tag)
  name1 = name.gsub(/\s/,"")
  file=File.join(ENV["LOCALAPPDATA"],"Microsoft Games",name,"#{name1}Settings.xml")
  outf =File.expand_path("~/#{name1}.txt")

  data = open(file,"rb",encoding:"ASCII-8BIT").read
  text = data[/#{ROOT}.*#{TOOR}/m].force_encoding("UTF-16LE").encode("UTF-8")
  doc  = REXML::Document.new(text)
  played = doc.root.get_elements("//#{tag}/GamesPlayed")[0].text.to_i
  won    = doc.root.get_elements("//#{tag}/GamesWon")[0].text.to_i

  out = [Time.now.strftime("%F"),played, won, won.to_f/played.to_f].join("\t")
  open(outf,"a"){|f| f.puts out}
end

game("Solitaire", "NoTimeScoringStats")

game("Hearts", "Stats")

game("Spider Solitaire", "StatsIntermediate")

Windowsで google-api-client を使うと一瞬コマンドプロンプトウィンドウが出る

google-api-clientを使ったスクリプトをRubyw.exeで動かしているが、起動時に一瞬だけコマンドプロンプト画面が出る。本当に一瞬なので何が出ているのかも見えない。


ということで、少しずつ実行してみて原因が分かった。
\google-api-client-0.10.1\lib\google\apis\version.rb で、

    OS_VERSION = begin
      if RUBY_PLATFORM =~ /mswin|win32|mingw|bccwin|cygwin/
        `ver`.sub(/\s*\[Version\s*/, '/').sub(']', '').strip

`ver`とコンソールプログラムを実行している。しょうがないので、とりあえず、

    OS_VERSION = begin
      if RUBY_PLATFORM =~ /mswin|win32|mingw|bccwin|cygwin/
        "Microsoft Windows [Version 6.1.7601]".sub(/\s*\[Version\s*/, '/').sub(']', '').strip

に書き換え(Windows7の場合)。
そもそもOS_VERSIONをどこで使っているのかみると、User-Agent文字列を作るところだけ。要らない〜〜

CentOS6 に Owncloud のインストール

借りているVPSのディスクにかなりの余裕があるので、プライベートDropbox風サーバーソフトを入れてみることにする。


ググればいろいろ参考になるページはあるが、ここはきちんと本家サイト http://download.owncloud.org/download/repositories/9.1/owncloud/ の手順でやることにする。

CentOS_6 owncloud-9.1.4-2

Run the following shell commands as root to trust the repository.

rpm --import https://download.owncloud.org/download/repositories/9.1/CentOS_6/repodata/repomd.xml.key

Run the following shell commands as root to add the repository and install from there.

wget http://download.owncloud.org/download/repositories/9.1/CentOS_6/ce:9.1.repo -O /etc/yum.repos.d/ce:9.1.repo
yum clean expire-cache
yum install owncloud

ただ、これでやると、yum install の依存チェックでPHPバージョンが5.4以上でないといけないと出る。

ということで、CentOS6にPHP5.4以上にアップデートする回り道。REMIリポジトリにある。
PHP7はチャレンジングな気がするので、REMIのPHP5の中で一番新しいPHP5.6にする事にする。

REMIリポジトリのインストール
# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
# vi /etc/yum.repo.d/remi.repo
で[remi-php56]をenabled=1に。
# yum clean all
PHPの更新
# rpm -qa "php*"

で、インストールされているPHPパッケージを調べる。下記の4つだけ。

# service httpd stop
# yum remove "php*"
# yum install php php-common php-cli php-mbstring
# service httpd start

で、既存のウェブコンテンツが影響を受けてないか確認する。駄目なら一旦戻して、PHPバージョンアップ対策。

再度Owncloudインストール
# yum clean all
# yum install owncloud

とりあえずインストールだけ完了。

サイトの更新チェック

サイトの一部が更新されたかどうかのチェック。
cronからの起動を想定。

#!/usr/local/bin/ruby
require "nokogiri"
require "open-uri"

def check(url:, xpath: nil, css: nil, file:)
    doc = Nokogiri::HTML.parse(open(url).read)
    text = doc.search(xpath||css).text

    file = File.expand_path(file,"~")
    if text != (open(file).read rescue nil)
        open(file,"w"){|f| f.print text}
        puts File.basename(file)
        puts text
    end
end

check(
    url:   "https://rubyinstaller.org/downloads/",
    xpath: "//li[@class='exe']",
    file:  "~/lib/rubyinstaller"
)

check(
    url:   "http://ruby.morphball.net/refm-remix.html",
    xpath: "//table/thead/tr/th",
    file:  "~/lib/ruby-refm"
)

環境変数LESSOPEN

ふと、環境変数LESSOPENの値を見ると、"||/usr/bin/lesspipe.sh %s" になっている。
CentOS6.8だと、/etc/profile.d/less.sh でそのように設定されているが、"|/usr/bin/lesspipe.sh %s"が正しいんじゃないのか?
なぜ"|"が2つあるのか謎。
"|||/usr/bin/lesspipe.sh %s" と3つにするとエラー。

forfilesコマンドのバグ?

ちょっと信じがたいけど、少なくともWindows7では、forfilesコマンドにバグがある。テストしてないのか?
/c で指定した外部コマンドの第一引数が落ちるようだ。cmd /c を書けば問題なし。

D:\foo>forfiles /c "gecho 1 2 3 @file"

2 3 bar
2 3 baz

D:\foo>forfiles /c "cmd /c gecho 1 2 3 @file"

1 2 3 bar
1 2 3 baz

D:\foo>

gecho.exe は gnu-echo コマンド。


第一引数が落ちることを前提にダミー文字列を書いた場合、バグが直ると正しく動かなくなるので、対応としては外部コマンドでも必ず cmd /c を書くことか。