gerry++
✖
✖
✖
gerry++
gerry++
✖
自分は色の数が少ない写真のほうが多いものより好きだってことがよくわかった。
✖
✖
gerry++
✖
✖
✖
神社にはよく行くけれど、自身としてはあまり信仰心がない(仏教よりはあるかも)ので、御参りして形式的に2拝2拍1拝はするものの、2拍のあとに何も思わないことが多かった。願いがないというわけではなくて、いない神様にそれを祈るぐらいなら、口に出して人に言ったりして、直接行動したほうが願いは叶いやすいと思っているからで、つまりどちらかというと積極的に祈らないということです。翻って考えてみると、祈らない代わりにお参りする度に自分の中で行動を起こす誓いを立ている感じに近い。
しかしちょっと考えかたを変えて、全く自分の行動の影響が及ばないことについて、例えば単純に運でしかないものについては祈ることにした。それ自体に全く意味がなくても、ある種の、運のみに依存している理不尽さに対抗するために効果があると考えた。これは暗い小説を読むのと似ていて、暗い小説なんて読んでも何の意味もないどころか辛い気持ちになりがちだけど、場合によっては溜飲を下げたり、現実において自分のネガティブな行動を抑えたりする効果があるなと思うわけです。
関連エントリー
- ✖ 頑張ったぶんだけ損したとか、頑張らなければ良かったと思わないようにしたい。これらはモチベーションコントロールの観点からいって、絶対にあっては...
- 『新装版 不安でたまらない人たちへ やっかいで病的な癖を治す』を読んだ 新装版 不安でたまらない人たちへ やっかいで病的な癖を治す cho45 ジェフリー・M・シュウォーツ ★ 4.0 / 5.0 cho45 こ...
- ✖ 死ぬ前にやることスタックという考えかたが通用しなくなったときのことを考えていた。最悪ケースの逃げ道が確保できなくなった場合、自分がどうなるか...
- ✖ 関東の神社巡りは非常にコストパフォーマンス (金銭というよりも時間的コスト) が悪くてめげる。大きな神社がそもそも少ないし、あっても行くのに...
- ✖ 何をするにせよ出てきて、自分をバカにしてくる鬱陶しいドヤ顔というのがあって、それを消滅させたい。 何をするにせよ頭にイメージとして自動的に浮...
✖
神社によく行くのは、前にも書いたかもしれないけど、雰囲気が良いから(大抵街中でも鎮守の森があるし)というのと、建築が面白いからというのと、だいたいどこの駅で降りても歩けばあるし、散歩とか外出の目標地点にするにはちょうどいいからという理由です。目標地点がないと外に出ないので……
✖
自分の考えかたの起源みたいなのに強い関心があって、つまりいろいろ自分の中に価値観ってものがあるけれど、それがどこ由来なのか、遺伝的によるものなのか、環境(教育、文化)によるものなのか、よく無駄に考えてしまう。
特に遺伝なのか環境なのかっていうのは、子供のころからよく考えることがあるけど、結局殆どよくわからない。
関連エントリー
- ✖ 自分は血統主義だな、とときどき思うところがあるが、一方では遺伝とは関係なく、環境・教育によって全てが決まるとも考えている節もある。 後者は理...
- ✖ あー無駄だったのだな、とふと思うときがあって、つまりあの、嫌で嫌で仕方ないことをしていたことというのが、ある程度報われるときがくるのではない...
- 『日本人の9割が知らない遺伝の真実』を読んだ 日本人の9割が知らない遺伝の真実 (SB新書) cho45 安藤 寿康 ★ 3.0 / 5.0 cho45 読んだ。急いで書いた感が文面から...
- ✖ 自分が言う「成功体験」というのは、自分で考えて自分で作ったもの (行動) が正しく社会に認められることなんだと思う。このような承認欲求という...
- 優生学はどう否定されるか、多様性はなぜ必要か 行動遺伝学に関する本を読んでから自分の中でちょっとモヤモヤした点を整理した。 優生学ってのは現代だとタブーとして扱われている。しかしこれは部...
✖
- 掃除機の紙パックがない
- 髪を切る必要がある
gerry++
✖
JSを編集してエディタで保存するとき、JSHint でコーディングバリデーションをかける
errormaker.vim を使って JS 保存時に末尾カンマチェックとかをやっていたのだけれど、今までチェックに使っていた Spidermonkey の最近のバージョンだと、strict モードにしても末尾カンマを warn しなくなって意味がなくなっていたので、JSHint でやるようにした。
setlocal makeprg=$HOME/.vim/vimparse.js\ %\ $* setlocal errorformat=%f:%l:%m
は今までのままにして、vimparse.js を以下のようにした。JSHint は JSLint よりはマイルドというか偏執さがないのだけど、まだ癖が強くて「実害のある」という警告と「単に好み」という警告がごっちゃになっていてうざいので、できるだけ自分でカスタマイズできるようにした。
node.js を実行環境にしているのは、node.js のインストールが特に依存もなく簡単だから (clone して make するだけでいいから) です。
#!/usr/bin/env node
var JSHINT = require("./jshint.js").JSHINT;
var fs = require("fs");
var argv = process.argv;
argv.shift();
argv.shift();
argv.forEach(function (filename) {
var source = fs.readFileSync(filename, 'utf-8');
var result = JSHINT(source, {
browser : true,
jquery : true,
evil : true,
passfail : false
});
if (!result) {
JSHINT.errors.forEach(function (error) {
if (!error) return;
if (error.reason.indexOf('Stopping, unable to continue.') != -1) return;
// 何これ?
if (error.reason.indexOf("Confusing use of '!'.") != -1) return;
// for (var i...) は何度も書きたい
if (error.reason.indexOf("'i' is already defined.") != -1) return;
if (error.reason.indexOf("'it' is already defined.") != -1) return;
// 可読性のために意図的にそうしているのでうざいし、そういう最適化は実行エンジンがすべきこと
if (error.reason.indexOf('is better written in dot notation') != -1) return;
// 根拠がわからないので保留
if (error.reason.indexOf("Don't make functions within a loop") != -1) return;
if (error.evidence) {
error.evidence = error.evidence.replace(/\t/g, ' ');
// 明示的に抑止されてるなら無視
if (error.evidence.indexOf('no warnings') != -1) return;
// やたら長い行は圧縮されたJSコードとみなす
if (error.evidence.length > 1000) return;
// 閉じブレース前のセミコロンは省略可能に
if (error.reason.indexOf('Missing semicolon') != -1 && error.evidence.substring(error.character).match(/^\s*\}/)) return;
}
console.log([filename, error.line, error.character].join(':') + "\t" + error.reason);
});
}
});
✖
一週間長い……
メモ 新規作成時のテキストエリアおかしい
✖
gerry++
✖
✖
✖
gerry++
✖
ほげ~
スマフォ編集~
編集~
てすとー
✖
✖
どうもこうも不安である。自分はどうしようもなくコミュニケーション能力に欠けた人間であり、人をひっぱる力がまるでない。加えて一般的な教養スキルがないため、いろんな点においてうまく立ち回ることができない。普通の人が行くような場所に行かず、自分と直接関係ない・興味のない施設を認識の外に置いてしまうので、いざそれらが必要になったときに、全く引き出しにものがない。
関連エントリー
- ✖ 自分にコミュニケーション能力がないことによって、かえってコミュニケーションの重要性について実感できるのは良い。伝えるべきこともあるし、伝える...
- ✖ 高校・大学と人間が心底嫌いになるばかりにコミュニケーション能力を得る機会の多くを失なって、いろいろと困ることになったということも、それによっ...
- ✖ 例えば、他人を誰とは言わず非難するようなポストがあると、だいたいどんな内容でも自分が言われているように思えて嫌な気分になる。特に正論だとどう...
- ✖ 「大金を手にしないほうがいい」という主張がどうやら嫌いで、そういうのを聞くとものすごく苛立ってしまう。その主張は実際に大金を手にした人が自分...
- 優生学はどう否定されるか、多様性はなぜ必要か 行動遺伝学に関する本を読んでから自分の中でちょっとモヤモヤした点を整理した。 優生学ってのは現代だとタブーとして扱われている。しかしこれは部...
✖
✖
✖
✖
gerry++
✖
✖
HTML メール
どうやって作るのが簡単なんでしょうか… 以下のようにしがちですがよくわかりません
use Encode;
use Email::MIME;
use Email::MIME::CreateHTML;
my $html = <<EOS;
<!DOCTYPE html>
<head>
<title>タイトル</title>
</head>
<body>
<h1>ああああ</h1>
</body>
</html>
EOS
my $text = <<EOS;
テスト
EOS
my $email = Email::MIME->create_html(
header => [
From => 'from@example.com',
To => 'cho45@lowreal.net',
Subject => encode("MIME-Header-ISO_2022_JP", 'タイトル'),
],
body => encode('iso-2022-jp', $html),
body_attributes => {
content_type => 'text/html',
charset => 'iso-2022-jp',
encoding => 'base64',
},
text_body => encode('iso-2022-jp', $text),
text_body_attributes => {
content_type => 'text/plain',
charset => 'iso-2022-jp',
},
);
print $email->as_string;
#use Email::Send;
#my $sender = Email::Send->new({mailer => 'SMTP'});
#$sender->send($email);
✖
TODO
- ドメイン更新
✖
✖
gerry++
✖
✖
昨日の写真と全く同じ構図だ。ピントあわせてる位置も一緒ですごいクセがついててよくない気がする。花の写真結構頭使わないで撮ってしまって良くないなー……
AnyEvent::setTimeout
AE::timer のインターフェイスが覚えられないなーと思うので、JS の setTimeout に似たものを書きました。
use AnyEvent::setTimeout;
setTimeout(sub {
warn "1sec!";
}, 1000);とか書けます。ちょっと細工をしていて、ファイルの最後に AnyEvent->condvar->recv とかおまじないを書かなくても、終了時に全てのタイマーの終了を待ちます (node.js 風にしたいけどできないのか的なことを言ってたら id:motemen:detail 先生ができそうなことを言ってくれたのでやってみた感じです)
ただ、このモジュールの管理下にあるタイマーしか終了時に待てないのがいまいち感あります……
とりあえず setTimeout さえあれば JSDeferred をそのまんま移植できるなーと思った感じなんですが、それやって意味があるのか謎なのでやめました。
まぁこういうの書いてるうちに AE::timer のインターフェイスとか覚えちゃうんですけど……
✖
おなかいたい
環境変数で設定を変える的なモジュール Config::ENV
なんかもっと簡単なのがあればいいなー と思ったのでつくりました。
package MyConfig;
use Config::ENV 'FOO_ENV';
common +{
name => 'foobar',
};
config development => +{
dsn_user => 'dbi:mysql:dbname=user;host=localhost',
};
config test => +{
dsn_user => 'dbi:mysql:dbname=user;host=localhost',
};
config production => +{
dsn_user => 'dbi:mysql:dbname=user;host=127.0.0.254',
};
config production_bot => +{
parent('production'),
bot => 1,
};
#
use MyConfig;
MyConfig->param('dsn_user');みたいに書くと、$ENV{FOO_ENV} の値によって別の値をつかうようにするってだけです。
設定ファイルを別にわけたいみたいなのは適当に do したらいいだけだし、切替える機能だけほしいのです。
✖
✖
写真コンテストは選外という結果がでました。残念ですがまあまあ細々とやっていきます。
gerry++
gerry++
Maildir のメールを Gmail にそのままインポートしたい
手元に昔使っていた Maildir 形式で保存されているメールがたくさんあるのを、Gmail にインポートしたいと思った。
残念ながら、いくら手元に完全な MIME のメッセージがあっても、Gmail にはそのままアップロードするみたいな機能がないために、簡単にそのままインポートすることができない。とはいえ Gmail には Mail Fetcher 機能 (POP3 で外部サービスのメールをとりにいく) というのがあるので、それを利用することにした。(メールで送ってしまう、という手もあるけど、From/To が書きかわったり、時刻が狂ったりして嫌だった)
いろいろ試した (Perl で Net::Server::POP3 を使ったり) した結果、結局必要な実装だけ自力で書いた。なんとなく TCP のサーバ実装を書くみたいなときは Ruby 使うのが手に馴染むので Ruby で書いた。割と簡単だったのでさっさと自力で書けばよかったと思った……
- 以下のスクリプトの冒頭をいい感じに設定
- パブリックなサーバでポート1110をあけて、起動する
- telnet [server] 1110 とかで接続できることを確認
- [設定] → [アカウントとインポート] → [POP3 を使用したメッセージの確認] から [POP3 のメールアカウントを追加] を選ぶ
- [メールアドレス] にインポートしたメールのメールアドレスを入れる (間違ってると正しくインポートされない)
- [ユーザ名] [パスワード] にスクリプト冒頭に設定したものを入れる
- [POP サーバー] に立ち上げたサーバのホスト名を入れる
- [ポート] は 1110 にする
- [アカウントを追加] ボタンをおすとたぶんうまくいく
#!/usr/bin/env ruby
USER = 'cho45'
PASS = 'xxxxxx'
MESSAGES = Dir.glob('./path/to/Maildir/cur/*')
require 'socket'
class POP3Session
def self.messages=(messages)
@@messages = messages
end
def initialize(s)
@s = s
authorization
end
def authorization
p :authrization
post "+OK POP3 server ready"
session do |command, args|
case command
when 'USER'
@user = args[0]
if @user == USER
post "+OK name is a valid mailbox"
else
post "-ERR never heard of mailbox name"
end
when 'PASS'
pass = args[0]
if pass == PASS
post "+OK maildrop locked and ready"
transaction
else
post "-ERR invalid password"
end
when 'QUIT'
@s.close
else
post "-ERR unknown command"
end
end
end
def transaction
p :transaction
session do |command, args|
p [command, args]
case command
when 'CAPA'
post "+OK capability list follows."
post "USER"
post "UIDL"
post "."
when 'STAT'
nom = @@messages.size # number of messages
size = @@messages.inject(0) {|r,i| r + i.size } # size of the maildrop in octets
post "+OK #{nom} #{size}"
when 'LIST'
if args.size.nonzero?
msg = args[0].to_i - 1
size = @@messages[msg].size
post "+OK #{msg} #{size}"
else
post "+OK scan listing follows"
@@messages.each_with_index do |m,i|
post "#{i+1} #{m.size}" unless m.deleted
end
post "."
end
when 'UIDL'
if args.size.nonzero?
msg = args[0].to_i - 1
post "+OK #{msg} #{@@messages[msg].hash}"
else
post "+OK message-id listing follows"
@@messages.each_with_index do |m,i|
post "#{i+1} #{m.hash}" unless m.deleted
end
post "."
end
when 'RETR'
msg = args[0].to_i - 1
m = @@messages[msg]
if m
post "+OK message follows"
post m.content
post "."
else
post "-ERR no such message"
end
when 'DELE'
msg = args[0].to_i - 1
m = @@messages[msg]
if m
m.deleted = true
post "+OK message deleted"
else
post "-ERR no such message"
end
when 'NOOP'
post "+OK"
when 'RSET'
@@messages.each do |m|
m.deleted = false
end
post "+OK"
when 'QUIT'
update
end
end
end
def update
p :update
post "+OK"
@@messages.reject! {|i| i.deleted }
@s.close
end
private
def post(msg="")
puts msg
@s.write("#{msg}\r\n")
end
def session(&block)
while line = @s.gets
line.chomp!
puts line
command, *args = *line.split(/\s+/)
res = yield command, args
end
end
class Message
attr_accessor :deleted
def initialize(file)
@file = file
end
def content
File.read(@file)
end
def size
File.size(@file)
end
end
end
server = TCPServer.open(nil, 1110)
puts "User: #{USER}"
puts "Pass: #{PASS}"
puts "POP3: %3$s Port: %2$s" % server.addr
POP3Session.messages = MESSAGES.map {|f|
POP3Session::Message.new(f)
}
loop do
begin
POP3Session.new(server.accept) # コネクションを1つずつしか受けつけないように
rescue => e
p e
end
endMail Fetcher の挙動メモ
- アカウント追加時に CAPA コマンドで UIDL コマンドが使えるかを見ている
- TCPセッションごとのメッセージ番号が 1 から順番の数値になっていないダメ
- 200件ごとにわけてインポートしようとする。200件ごとに STAT / LIST / RETR / DELE が走る
- (Gmail 的に) 同じ Message-ID のメールは重複しないので、何度実行しても大丈夫
- TRANSACTION フェーズで QUIT を発行したあと、こちらの応答を待たずに接続を切るっぽい
- うまくメッセージの削除が行われないうちに次のセッションがはじまるので困る → 接続を1ずつにすることで解決
✖
✖
✖
今週あったよかったことさがし
- POP3 に詳しくなった
gerry 可視化再び
use strict;
use LWP::Simple qw($ua);
use HTML::TreeBuilder::XPath;
my $res = $ua->get('http://subtech.g.hatena.ne.jp/keyworddiary/gerry');
$res->is_success or die "Failed to GET: $res";
my $data = [];
my $doc = HTML::TreeBuilder::XPath->new_from_content($res->content);
my $nodes = $doc->findnodes('id("refered-diary")//ul/li[@class="diary-listitem"]/a');
for my $node (@$nodes) {
my $href = $node->findvalue('@href');
if (my ($year, $month, $day) = ($href =~ m{/cho45/(\d{4})(\d\d)(\d\d)})) {
push @$data, [$year, $month, $day] ;
}
}
$doc->delete;
use WebService::Hatena::Graph;
use IO::Prompt;
use Perl6::Say;
my $password = prompt "Password:", -echo => '';
my $graph = WebService::Hatena::Graph->new(
username => 'cho45',
password => $password,
);
my $count = 1;
for my $date (reverse @$data) {
$graph->post_data(
graphname => 'gerry',
date => join('-', @$date),
value => $count++,
);
say join('-', @$date);
}
use DateTime;
use IO::File;
my $fh = IO::File->new('gerry_access_log', 'w');
for my $date (@$data) {
my ($year, $month, $day) = @$date;
my $dt = DateTime->new(year => $year, month => $month, day => $day, time_zone => 'Asia/Tokyo')->strftime('%d/%b/%Y:00:00:00 +0900');
$fh->write(qq|0.0.0.0 - - [$dt] "GET /gerry HTTP/1.1" 200 26768 "-" "Gerry"\n|);
}
$fh->close;
✖
Hatena::Counter IRC Gateway
を書きました
- PASS に javascript:alert(document.cookie.match(/rk=(\S+)/)[1]); を指定
- /join #counter-{userid}-{counterid} する
と適当にクロールして IRC ログにアクセスがながれてきます。
UA とリモートホスト (を削ったもの) を元に ua_id というのを作って nick にしているほか、リモートホスト部分に色をつけるようにしてます。



































