Windows8でもっともっとインクレディブル・マシーン for Windows95を動かす。

研究室出る前に実家のMeマシンのHDD中身吸出しをしてもらったのですが、そこからもっともっとインクレディブル・マシーンを発掘出来ました。
互換モード使っても全くまともに動く気配がなかったので、とりあえずfor all incrayersさんのところにいったらパッチがありました。インクレで困ったらこのサイト以上のところはないと思います。すごいなぁ。

互換性パッチ – for all incrayers

Win8の場合、このパッチを当てたままだと正常に動かないので、
互換モードでXPのSP3・カラー256色
を設定して起動すると遊べるようになります。

Web::ScraperとNet::Google::Calendarをあわせて使う。

過去に北海道ライフル射撃協会の紹介(動画あり) の内容をWeb::ScraperでスクレーピングしてNet::Google::Calendarで投稿するスクリプトを書きました。
が、サンプルに使ってたページが無くなってました。
スクレーピングする元さえあれば動くスクリプトなのでそのまま貼っておきます。

これを応用すると色んなページのHTMLで書いてある予定とかをGoogleカレンダーに投稿できます。
例えばHTMLで書いてた昔の日記のタイトルを$entry->content(‘content’)で内容と一緒に投稿するとか。

use utf8;
use strict;
use warnings;

use Web::Scraper;
use URI;
use DateTime;
use Net::Google::Calendar;


# HTMLスクレーピング
my $scraper = scraper {
	 process '/html/body/table/tbody/tr/td/table/tbody/tr/td/div[2]/div[3]/table/tbody/tr[2]/td[2]', 'date' => 'HTML';#日付の書いてあるtdまでのXPath
	 process '/html/body/table/tbody/tr/td/table/tbody/tr/td/div[2]/div[3]/table/tbody/tr[2]/td[3]', 'nakami' => 'HTML';#内容までのXPath
};

# URL
my $uri = new URI('http://www.h3.dion.ne.jp/~moasa/shoukai.html');

# オブジェクト生成
my $res = $scraper->scrape($uri);

#########データ整形#################### 
my $temp = $res->{date};
$temp =~ tr/0-9A-Za-z/0-9A-Za-z/;#全角数字を半角に
$temp =~ s/<br \/>/\n/g;
$temp =~ s/<font [^>]*">|<\/font>//g;
my @daylist = split(/\n/, $temp);

##
my $temp2 = $res->{nakami};
$temp2 =~ tr/0-9A-Za-z/0-9A-Za-z/;
$temp2 =~ tr/:/:/;
$temp2 =~ s/<br \/>/\n/g;
$temp2 =~ s/<font [^>]*">|<\/font>| //g;
$temp2 =~ s{\x{301c}}{\x{ff5e}}g; #波ダッシュ変換
$temp2 =~ s/~/-/g;
my @titlelist = split(/\n/, $temp2);
########################################

# Google カレンダーへのログイン処理 
my $private_url = 'https://www.google.com/calendar/feeds/カレンダーID@group.calendar.google.com/private-カレンダーID/basic';
my $username = '***@gmail.com'; # x...@gmail.com 
my $password = '***'; #パスワード

# オブジェクト生成
my $cal = Net::Google::Calendar->new( url => $private_url ); 
$cal->login($username, $password); 

my $counter = 0;
my $datetemp;
my $flag = 0;

my $dt = DateTime->now;
my $year  = $dt->year; #今年の西暦取得

foreach my $title (@titlelist) { #イベントのタイトル

	my $date = $daylist[$counter]; #イベントのタイトルと対になる日付
	$counter++;

	my $entry = Net::Google::Calendar::Entry->new();
	$entry->status('confirmed');
	$entry->transparency('transparent'); 
	$entry->visibility('private'); #一般公開する場合public

	if ($date eq "\n" || $date eq "") { $date = $datetemp; }
	chomp($date);

	my $next;

	my @list = ($date =~ /\d+/g); #日付の数字だけ取得
	my $num = @list;
	if ($num != 2){
		$next = $list[2] - $list[1];
	}
	my $month = $list[0];
	my $day = $list[1];

	if ($month == 12) {$flag = 1;}

	my $hour = 0;
	my $allday = 0;
	my $plus = 0;

	if ($title =~ /(\d{1,2}):(\d{1,2})-(\d{1,2}):(\d{1,2})/) {
		$hour = $1;
		$plus = $3 - $1;
		$title =~ s/\d{1,2}:\d{1,2}-\d{1,2}:\d{1,2}//g;
	}
	elsif ($title =~ /(\d{1,2}):(\d{1,2})-$/) {
		$hour = $1;
		$plus = 24- $1;
		$title =~ s/\d{1,2}:\d{1,2}-//g;
	}
	else {
		$allday = 1;
	}

	if ($month < 12 && $flag == 1) {
		$year++;
		$flag = 0;
	}

	if (defined($next)) { #日付をまたぐ場合
		my $dt = DateTime->new(
    			time_zone => 'Asia/Tokyo',
    			year      => $year,
    			month     => $month,
    			day       => $day
		);
		my $dt2 = $dt + DateTime::Duration->new( days => $next+1 );
		my $dt3 =  $dt2->add( days =>1 );
		$entry->when($dt->add( days =>1 ), $dt2, $dt3);
	}
	elsif ($allday == 1){ #終日の場合
		my $dt = DateTime->new(
    			time_zone => 'Asia/Tokyo',
    			year      => $year,
    			month     => $month,
    			day       => $day
		);
		$entry->when($dt,$dt->add( days => 1 ),$dt);
	}
	else {
		my $dt = DateTime->new( #時間指定の場合
			time_zone => 'Asia/Tokyo',
			year      => $year,
    			month     => $month,
    			day       => $day,
    			hour      => $hour,
    			minute    => 0
		);
		$entry->when($dt, $dt+DateTime::Duration->new( hours => $plus ));
	}

	$entry->title($title);
	$cal->add_entry($entry); #カレンダーにイベントを投稿

	$datetemp = $date;
}

Google Chrome拡張からOAuthを使用してGoogleカレンダーにイベント登録する。

以前はてなブログに投稿した記事(URL失念)の改訂版です。

OAuth認証を利用し、Googleカレンダーにイベント登録するためのGoogle Chrome拡張を作ります。
#manifest.jsonは割愛します。

用意するもの

[chrome] Index of /trunk/src/chrome/common/extensions/docs/examples/extensions/oauth_contactsから以下の4つをダウンロードします。

  • chrome_ex_oauth.html
  • chrome_ex_oauthsimple.js
  • chrome_ex_oauth.js
  • onload.js

OAuth認証を利用するためのライブラリ群なのですが、中身はよくわかんなかったです。
ちなみにTutorial: OAuth – Google Chromeは未だにonload.jsを用意しろって書いてないですね…。onload.jsが必要になったのはchrome extensionのmanifestがv2でhtmlに直接スクリプトが書けなくなったのが原因で、呼び出し元はchrome_ex_oauth.htmlです。チュートリアルページにも詳しいサンプルコードがありますので、一度目を通しておくと役に立ちます。

background.js

スクリプトの本体です。今回はコンテキストメニューで呼び出すとイベントが登録されるようなものにしました。コード見たらだいたい何やってるかわかると思います。
注意点として、終日設定のイベントを登録する場合、時刻の登録は無し・終了日は設定したい日付に+1日する必要があります。カレンダーのIDはカレンダーの設定から取得出来ます。

chrome.contextMenus.create({
	"title" : "カレンダーに投稿",
	"type" : "normal",
	"contexts" : ["selection"],//テキストを選択した時のみ
	"onclick" : getClickHandler()
});

var oauth = ChromeExOAuth.initBackgroundPage({//OAuth設定
	"request_url": "https://www.google.com/accounts/OAuthGetRequestToken",
	"authorize_url": "https://www.google.com/accounts/OAuthAuthorizeToken",
	"access_url": "https://www.google.com/accounts/OAuthGetAccessToken",
	"consumer_key": "anonymous",
	"consumer_secret": "anonymous",
	"scope": "https://www.google.com/calendar/feeds/"
});


function getClickHandler() {
	return function(info, tab) {
		oauth.authorize(function(){//OAuthToken取得完了時に呼ばれる関数

			/**開始~終了日時設定**/

			var st ="";//開始日時
			var en ="";//終了日時

			var check = true;//終日設定フラグ

			if(check){//終日設定にする場合
				st = "yyyy-mm-dd";
				en = "stの日付に+1日した値";//+1しないと意図したとおりに設定出来ません
			}
			else {
				st = "yyyy-mm-dd(開始日)" + "T" + "hh" + ":" + "mm" + ":00.000+09:00";
				en = "yyyy-mm-dd(終了日)" + "T" + "hh" + ":" + "mm" + ":00.000+09:00";
			}
			/**設定終わり**/

			/**登録したいイベントのJSON*/
			var body = JSON.stringify({

				"data": {
					"title": "イベントのタイトル",
				"details": "イベントの内容",
				"transparency": "opaque",
				"status": "confirmed",
				//"location": "場所",
				"when": [
				{
					"start": st,
					"end": en
				}
				]
			}
			});

			oauth.sendSignedRequest(//リクエストの送信

				"https://www.google.com/calendar/feeds/" + "登録したいカレンダーのID" + "/private/full",

				function(response){//コールバック関数
					try{
						var p_res = JSON.parse(response);
						if(p_res.error){//エラー処理
							var err = p_res.error;
							alert("Error:" + err.message);
						}else{
							alert("登録完了しました");
						}
					} catch(e) {
						alert("Error:" + response);
					}
				},

				{
					"method": "POST",
					"headers": {"Content-Type": "application/json"},
					"body" : body
				}
			);
		});
	}
}

background.html

スクリプトを呼び出すためのbackground.html

<!doctype html>
<html>
	<head>
		<meta charset="utf-8" />
		<script src="chrome_ex_oauthsimple.js"></script>
		<script src="chrome_ex_oauth.js"></script>
		<script src="background.js"></script>
	</head>
	<body>
		<!--バックグラウンドです!-->
	</body>
</html>

初回呼び出し時にのみOAuth認証画面に飛ばされたあと、通常通り使えるようになります。
認証を解除したい場合は、拡張が使用しているlocalStorage変数を削除すれば大丈夫です。

シャープのスマートフォンでなかよしボックス機能を使う。

A01しか知らないけどシャープのスマホなら多分できるはず。
(なかよしボックス:自分が送った特定の人物宛のメールとその人物からのメールの一覧が時系列順で見られる機能)

電話帳→なかよしボックスを使いたい相手を選択→吹き出しをタップ

A01使って2年近く経とうとしてるのに今の今まで知りませんでした。しかも着信・発信まで見られるしすげえ便利。

Windows8でWindows Update(KB2822241)に失敗する場合の対策。

Windows8にしてからUIがクソすぎてモニタ叩き割りそうになったことが何度もあった以外は特に大きなトラブルにも見舞われなかったのですが、Windows UpdateのKB2822241のインストール(正確には再起動中に行う構成)に何度も失敗したため、いろいろ調べてみました。
(ちなみにエラーコードでぐぐっても全然解決策見つからなかったのと、毎回コードが違ってまるで参考にならなかったので、コードはメモってません。)

KB2822241のインストール失敗 – マイクロソフト コミュニティ
ここが一番参考になりました。プリインストール系の何かがいろいろモリモリ動いてるので、それと競合してだめなんだろうなーって気がしたのでクリーンブートを試してみたら見事にうまくいきました。
Windows Vista、Windows 7、または Windows 8 でクリーン ブートを実行して問題のトラブルシューティングを行う方法

しかし何と競合してだめだったのかわからないのがモヤモヤしますね…。いらないサービスとスタートアップは切れるだけ切ってるんですが…。