0. Skype::Anyを入れる
akiym/Skype-Any · GitHub からどうぞ
1. Net::DBus::Skype::APIを入れる
akiym/Net-DBus-Skype-API · GitHub からどうぞ
2. AnyEvent::DBusを入れる
% cpanm AnyEvent::DBus
これで動くかもしれません。
0. Skype::Anyを入れる
akiym/Skype-Any · GitHub からどうぞ
1. Net::DBus::Skype::APIを入れる
akiym/Net-DBus-Skype-API · GitHub からどうぞ
2. AnyEvent::DBusを入れる
% cpanm AnyEvent::DBus
これで動くかもしれません。
Macでは使えませんが、Linuxでは使えます(手元で動きました)。
MacのSkypeはバージョンアップして、レスポンスが非同期で返ってくるようになったので(仕様らしいです。うえー)、Mac環境では思ったように動きません。メッセージを送信だけするといったことは可能ですが。
ってことで現状でした。
Skype::Anyのよくないところは、ドキュメントを書いてないところだと思うので、いまさらですが、解説不足だったところを解説します。
基本的にSkype APIではメッセージを送るときにはチャットのidが必要です。
Skype::Any::Chat->new($id);
しかし、チャットのidは普段見ることができません。このidは内部的なものだからです。Skype APIを使って見ることができますが、とりあえず、idを作る方法を説明します。
例えば、echo123とのチャットのidはこのようにして見ることができます。$user->chat()で、チャットを*作る*ことができます。
$chatは、Skype::Any::Chatオブジェクトなので$chat->send_message()でメッセージを送信することができます。
my $user = Skype::Any::User->new('echo123');
my $chat = $user->chat;
$chat->{id};
$chat->send_message('hello!');
$user->chat()をいくら呼んでもecho123とのチャットのidは変わりません。
それでは、グループチャットの場合はどうなるでしょうか。先ほどの例は、1対1のチャットでした。複数の人とのチャットの場合はこのようになります。
ユーザー名をカンマで区切るだけです。あとは同じです。
my $user = Skype::Any::User->new('echo123,t.akiym');
my $chat1 = $user->chat;
$chat1->{id};
$chat1->send_message('hello!');
my $chat2 = $user->chat;
$chat2->{id};
$chat2->send_message('good bye!');
グループチャットの場合は$user->chat()のたびにチャットのidが変わります。つまり、新しいチャットが作成されてしまうということです。注意してください。
以上がチャットを新しく作成する方法です。でも、Botが発言するたびに新しいチャットが作成されるの嫌ですよね。
そんなときは、チャットのidからSkype::Any::Chatオブジェクトを作成します。そうすることですでに存在するチャットにに対して$chat->send_message()でメッセージを送信することができます。
my $chat = Skype::Any::Chat->new('#t.akiym/$d0656290604bd99b');
$chat->send_message('XD');
しかし、チャットのidは内部的なものです。普段見ることはできません。
ここでtipsを紹介します。このようにすることで最近のチャット履歴からチャットのidを見ることができます。@chatsにSkype::Any::Chatのオブジェクト(すでに存在するチャット)が入っています。
ちなみに、$skype->send_command()はSkype APIを直で叩くことができるメソッドです。
my $skype = Skype::Any->new;
my $res = $skype->send_command('SEARCH RECENTCHATS');
$res =~ s/^CHATS\s+//;
my @chats = map { Skype::Any::Chat->new($_) } split /,\s+/, $res;
ほかの方法としては、$skype->message_received()はコールバックにSkype::Any::ChatMessageのオブジェクトを渡してくれるのでそこから$msg->chat()でSkype::Any::Chatのオブジェクトを取ってくるのもありでしょう。$msg->chat()はいくら呼んでも新しいチャットが作られることはありません(1対1でもグループチャットでも)。
my $skype = Skype::Any->new;
$skype->message_received(sub {
my ($msg) = @_;
$msg->chat;
$msg->chat->send_message();
});
せっかくなので、Skype::Anyを使ったSkype botのサンプルをGithubにあげました。適当に書いたものなので勘弁してください。
akiym/p5-skypebot · GitHub
とりあえず、検索してみるとIRCのログのようなものにヒットした。
http://ngxbot.lustfield.net/logs/%23nginx/2012/02/%23nginx.03.log
英語でよくわからないけど、HTTP 1.1があやしいみたいなことを言っているので、
proxy_http_version 1.1;
をconfに追加したらエラーを吐かなくなって、正常なレスポンスを返すようになった。
でもこれでいいのかわからないので、また後で調べる。
perlのプログラミングについての質問です。
大学の授業の小テストなのですが、よろ... - Yahoo!知恵袋 より
円の半径を入力すると「その円の面積」を出力するプログラムを作り、 作成したプログラムに半径として以下の値を入力した場合に、 それぞれの出力として得られる面積を答えよ。 ただし、円周率は 3.14 とし、 半径として負の数が入力された場合は0が入力されたとして計算すること。
答え
''=~('('.'?'.'{'
.('`'|'%').('['^'-').(
'`'|'!').('`'|',').('"').(
'`'|'-').('['^'"').('{'^"\[").
'\\'.'$'.('['^')').('{'^'[').'='
.('{'^'[').'<'.'>'.';'.('!'^"\+").
'\\'.'$'.('['^')').('{'^'[').'='.(
'{'^'[').('^'^('`'|'.')).('{'^'[').(
'`'|')').('`'|'&').('{'^'[').('\\').
'$'.('['^')').('{'^'[').'<'.('{'^'['
).('^'^('`'|'.')).';'.('!'^'+').('['
^'+').('['^')').('`'|')').('`'|'.').
('['^'/').('{'^'[').('^'^('`'|'-')
).'.'.('^'^('`'|'/')).('^'^(('`')|
'*')).('{'^'[').'*'.('{'^('[')).
'\\'.'$'.('['^')').('{'^"\[").
'*'.'*'.('{'^'[').(('^')^(
'`'|',')).';'.('!'^'+'
).'"'.'}'."\)");
あまりカスタマイズしてないけど。
今は使ってない機能とかも残ってると思うし、ただコピペしてきただけのところもあるので注意。
ひとつひとつコメントを書こうかなと思ったけど、面倒だったのでやめた。
set titlestring=Firefox
set ignorecase
set complete=Sl
set focuscontent
set visualbell
set activate=homepage,quickmark,tabopen,paste
set hintmatching=custom
colorscheme indigo
map j 5<C-e>
map k 5<C-y>
cmap <C-n> <TAB>
cmap <C-p> <S-TAB>
cmap <C-i> <TAB>
map h <C-p>
map l <C-n>
com! -complete=bookmark -nargs=+ ob :t <args>
com! -complete=history -nargs=+ oh :t <args>
map ,b :ob
map ,h :oh
nnoremap <C-g> g<C-g>
noremap ! :open javascript:(function()%7Bvar%20s=document.createElement('style');s.type='text/css';s.innerHTML=%22*%7Bfont-family:'IPAMonaPGothic'%20!important;font-size:12pt%20!important;%7D%22;document.getElementsByTagName('head')%5B0%5D.appendChild(s);%7D)();<CR>
set history=0
style chrome://* #statusbar-display[type="overLink"] {display: none !important;}
set! ui.key.generalAccessKey=0
set nextpattern=^次(へ|の|ペ)?,^続き,NEXT,(next|more),^(>>*|»)
set previouspattern=^前(へ|の|ペ)?,^戻る,BACK,(prev|previous),^(<<*|«)
let g:nextlink_nositeinfo_act = "f"
let g:hints_for_embedded_mode="e"
noremap ;e :embhint<CR>
let use_hints_ext_hinttags=1
let use_hints_ext_extendedhinttags=1
silent command! -nargs=+ lazy autocmd VimperatorEnter .* <args>
"lazy fmaps -u='www\.google\.co(m|\.jp)/reader' -events=vkeypress j k n p m s v A r S N P X O gh ga gs gt gu u / ? J K
"lazy fmaps -u='fastladder\.com/reader' -events=vkeypress s a r w W c j k z p o v > < f
lazy fmaps -u='reader\.livedoor\.com/reader' -events=vkeypress s a r w W c j k z p o v > < f
silent bmark -title="google" -tags=keyword -keyword=g http://www.google.co.jp/search?q=%s
silent bmark -title="twitter" -tags=keyword -keyword=tw http://twitter.com/%s
silent bmark -title="nico" -tags=keyword -keyword=ni http://www.nicovideo.jp/search/%s
silent bmark -title="nico sm" -tags=keyword -keyword=sm http://www.nicovideo.jp/watch/sm%s
silent bmark -title="nico ranking" -tags=keyword -keyword=nira http://www.nicovideo.jp/ranking
silent bmark -title="cpan" -tags=keyword -keyword=cpan http://metacpan.org/search?q=%s
silent bmark -title="google translate" -tags=keyword -keyword=tr http://translate.google.co.jp/translate_t?q=%s
javascript <<EOM
liberator.globalVariables.copy_templates = [
{ label: 'url', value: '%URL%', map: 'y' },
{ label: 'titleAndURL', value: '%TITLE% %ENCODEDURL%', map: ',y' },
{ label: 'title', value: '%TITLE%' },
{ label: 'anchor', value: '<a href="%ENCODEDURL%">%TITLE%</a>' },
];
EOM
javascript <<EOM
liberator.globalVariables.stella_nico_use_comment=true
function addLocalMappings(buffer, maps) {
maps.forEach(
function (map) {
let [cmd, action, extra] = map;
let actionFunc = action;
extra || (extra = {});
if (typeof action == "string") {
if (action.charAt(0) == ':')
actionFunc = extra.open ? function () commandline.open("", action, modes.EX)
: function () liberator.execute(action);
else
actionFunc = function () events.feedkeys(action, extra.noremap, true);
}
extra.matchingUrls = buffer;
mappings.addUserMap(
[modes.NORMAL],
[cmd],
"Local mapping for " + buffer,
actionFunc,
extra
);
}
);
}
addLocalMappings(
/^(http:\/\/(es|www).nicovideo.jp\/(watch|playlist\/mylist)|http:\/\/(jp|www)\.youtube\.com\/watch|http:\/\/(www\.)?vimeo\.com\/(channels\/(hd)?#)?\d+)/,
[
['<C-g>', ':pageinfo S', ],
['p', ':stplay', ],
['m', ':stmute', ],
['c', ':stcomment', ],
['zz', ':stlarge', ],
['s', ':stseek! 15', ],
['S', ':stseek! -15', ],
['v', ':stvolume! 10', ],
['V', ':stvolume! -10', ],
['e', ':strelations ', {open: true}],
['E', ':strelations! ', {open: true}],
]
);
EOM
プラグイン一覧
% ls ~/.vimperator/plugin _libly.js hints-yank-paste.js prevent-pseudo-domain.js caret-hint.js migemo-find.js sbmcommentsviewer.js copy.js migemo_completion.js statusline-toolbar.js feedSomeKeys_3.js migemo_hint.js stella.js hints-ext.js nextlink.js
とりあえずfeedSomeKeys_3.jsとstella.jsは必須。migemo系はFirefoxのアドオンのXUL/Migemoと合わせて使う。
prevent-pseudo-domain.jsは:t jquery.jsとしたときにhttp://jquery.jsに飛ばずに検索してくれるもの。
実際、FirefoxってVimperatorだよね。
気がつくと勝手にFirefoxのバージョンが12.0になっていて、うわーとなってしまいました。それだけなら別にいいのですが、CocoaのEmacsキーバインド(C-hやC-wなど)が使えなくなってしまいました。
Vimperator
というわけでVimperatorのアップデートをします。
リポジトリをcloneしてきて、xpiを作成するだけです。gsedとgcpがない場合はgnu-sedとcoreutilsを入れておけばおk(必要なのはMac環境のみ)
% hg clone https://vimperator-labs.googlecode.com/hg % make xpi -e SED=gsed CP=gcp
xpiがdownloads/に作成されるのでそれをアドオンとしてインストールするだけです。
そういえば、Firefox 12.0のアップデートしたことではてなブログの記事が書けなくなりました(何かのアドオンが関係している可能性もありますが)。
後で調べないと。
ちなみにこの記事はGoogle Chromeを使って書いています。
- OSコマンドインジェクションは本当にめずらしい
- 釣りでいうとイトウ(本人談)
- キャッシュからの情報漏洩
- リバースプロキシ、フォワードプロキシ、ブラウザのキャッシュ機能
- アプリケーションの負荷軽減
- 「別人問題」
- 原因のひとつがキャッシュ
- Squidのキャッシュ
- override-lastmod
- OpenPNE
- サトーさん
- /diary/2 自分の日記
- 自分の日記が見れなくなる場合も
- タナカさん
- /diary/1 自分の日記
- ブラウザのキャッシュ
- はてなブックマーク(プライベート)
- ログイン→ログアウト
- /ockegthm2 見えた
- ブラウザのキャッシュが残っていたから
- ブラウザを再起動しても見えた
- ブラウザを共有することなんてない
- 許容してもいいかも
- 対策
- セキュアプログラミング講座より
- Cache-Control: no-store
- BK
- HTTP/1.0
- Pragma: no-cache
- クエリにランダムな数字
- ANAのサイト
- /fs/domjpmenu?rand=20120421131830
- 見守ってあげて
- クリックジャッキング
- iframeの上で「透明に」表示
- demo
- twitter
- 「僕本当はPHP嫌いなんだ #phpcondo」
- 画像を重ねる
- 後ろのボタンを押してしまう
- Firefox 3
- …
- x-frame-options: deny 禁止して良い場合
- x-frame-options: sameorigin
- CSRFとの関係
- トークン埋め込み
- ついでにx-frame-optionsヘッダ出力
- Ajaxセキュリティ入門
- 入門書の問題
- '<p>' + json[i].caption + '</p>'
- データにJavaScriptを入れてみる
- XSS
- 原因と対策
- HTMLエスケープ
- evalインジェクション
- jQueryは安全にやってくれる
- $.get ($.getJSONではない)
- eval(text)
- データにJavaScriptを入れてみる
- ""+alert("1")+""
- XSS
- 対策
- 自前でJSON生成するな!
- evalでJSON解釈するな!
- json.phpを直接ブラウズ
- "キャプション1<body onload=alert(1)>"
- Content-Type: application/json
- IEだけ
- IE9
- URLに/a.htmlをつけると…
- HTMLとして解釈されてしまう
- X-Content-Type-Options: nosniff つけないのは死ね!
- IE7だとだめ
- 対策
- nosniff
- application/json; charset=utf8
- IE7
- <, >もエスケープ
- \u003Cでエスケープされる
- HTMLとして解釈されているけど、JavaScriptとしては実行されない
- JSONハイジャック
- 別ドメインのJSONを罠サイトからscript要素で読み出す
- 正規のCookieが送信される→JSONが取得できる
- ソース上に置いてあるだけなので大丈夫
- Object.prototype.__defineSetter__
- 読めてしまう!
- Firefox 11.0だと問題なし
- Androidの標準ブラウザでハイジャック成功
- 対策
- script要素からのリクエストにはレスポンスを変えさない
- x-requested-with: xmlhttprequest
- POST? 好まない
- for(;;)を置く? 好まない
- ドリランド増殖祭
- demo(こうだったかも)
- 鳥ランド カード交換
- select, insert, 番号振りなおす, 元カードをdelete
- 同時にやる
- 増えた!
- 対策
- トランザクション
- ロック
- SELECT .. FOR UPDATE
- 同時にやってみる
- 片方はSELECTしたけど読めずに終わる
- トランザクションは学ぶの難しいよね
- NoSQL, Memcached, DBのパーティショニングやシャーディング
- レプリケーション, LDAPやファイルなどのトランザクション未対応のもの