コマネタ帳(旧) by iyoupapa

PCや土いじりやゲームやオモチャ、思いつくまま細切れネタを書き散らかす日記

Creative Commons Licenseiyoupapaが書いたコマネタ帳の文章は「Creative Commons 表示-継承 2.1 日本」ライセンスです。写真については私のFlickrで配布しています。新しい「コマネタ帳」に移転しました。

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[プログラミング]TwitterのBotをOAuth対応にする

第15回北海道開発オフ@JRHokkaidoSapをOAuth対応に修正したときのメモ。

1.アプリケーションの登録

  • アプリケーション作成者のアカウント(この場合@iyoupapa)でTwitterにログインして「Twitter / アプリケーション」から「Register a new application」を選択する。
  • 「Application Icon」を設定する。
  • 「Application Name」にアプリケーション名を適当に入れる。
  • 「Description」に最低30文字を入れる。
  • 「Application Website」にこのブログのURLを入力する。
  • 「Application Type」を「Client」にする。
  • 「Default Access Type」を「Read & Write」にする。
  • 個人なので、「Organization」、「サイト」は空欄にする。
  • 「Use Twitter for login」はチェックしない。
  • CAPTCHAを入力して登録する。
  • 登録後の「Consumer key」と「Consumer secret」をコピペ保存する。

2.アクセストークンの取得

  • Net::Twitterを準備する。Windows の ActivePerlの時はPPM(Perl Package Manager)からNet-Twitterをインストールする。
  • Twitterに「Botが動作するアカウント(この場合@JRHokkaidoSap)」でログインする。
  • 以下のコードにConsumer keyとConsumer secretを書き込んで実行する。
  • 表示されたURLにアクセスして、アクセスを許可する。
  • 数字が大きく表示されるので、その数字を先ほどのスクリプトに入力する。
  • 「Access token」と「Access token secret」が表示されるのでコピペ保存する。
#!/user/bin/perl
use strict;
use warnings;

use utf8;
use Encode;
use Net::Twitter;

binmode STDOUT, ':encoding(shiftjis)';
binmode STDERR, ":encoding(shiftjis)";

my $nt = Net::Twitter->new(
  traits      => ['API::REST', 'OAuth'],
  consumer_key  => "CONSUMERKEY",    # ←
  consumer_secret  => "CONSUMERSECRET", # ←
);

my $access_token;
my $access_token_secret;

unless ( $nt->authorized ) {
  # The client is not yet authorized: Do it now
  print "Authorize this app at ",
   $nt->get_authorization_url,
   " and enter the PIN#\n";

  my $pin = <STDIN>; # wait for input
  chomp $pin;

  my($access_token, $access_token_secret, $user_id, $screen_name) = $nt->request_access_token(verifier => $pin);
  #  save_tokens($access_token, $access_token_secret); # if necessary
  print "Access token: ", $access_token, "\n";
  print "Access token secret: ", $access_token_secret, "\n";
}

3.本体スクリプトの修正

  • ログイン部を修正する。
sub initTwitter
{
  $bot = new Net::Twitter( 
    traits           => ['API::REST', 'OAuth'],
    consumer_key     => $CONSUMER_KEY,
    consumer_secret  => $CONSUMER_SECRET,
  );
  $bot->access_token($ACCESS_TOKEN);
  $bot->access_token_secret($ACCESS_TOKEN_SECRET);
}

4.多分OK!

お疲れ様でした。…いやまだ実環境に適用していないんだけどw。

5.おまけ

PPMもNet::Twitterもプロクシを超えるときは環境変数HTTP_PROXYに”http://proxyhost:8080/”などと設定しておけばいい。LWP::UserAgentは環境変数だけでは認識しないので、env_proxyを呼び出す。

  my $ua = LWP::UserAgent->new;
  $ua->env_proxy;

これまでプロクシのない環境ばかりだったので、こんな基本も知らないのさ><。

6.Thanks

スポンサーサイト

[プログラミング]TomblooでFlickrからpostするときlinkになる不具合パッチ

2010/01/05追記

toさんがTombloo本体へ修正パッチをCommitしてくれました。現行の0.4.5の次のバージョンからこのパッチは不要になるはずです。

第13回北海道開発オフでTomblooのパッチを作りました。本当はGithubからTomblooを持ってきてパッチするべきなんでしょうけど、アドオンの開発環境がないのでテストできない罠orz。

FlickrPatch.jsをtomblooのscriptフォルダに突っ込んでください。ソースは以下。

(function() {
Tombloo.Service.extractors['Photo - Flickr']['check'] = function(ctx){
	if (ctx.target.id=="photo-drag-proxy"
	 && ctx.host.match(/\.flickr\./)) {
		var t = $x('..//img[@class="reflect"]', ctx.target);
		if (t) {
			ctx.target = t;
			ctx.onImage = ctx.target instanceof Ci.nsIDOMHTMLImageElement;
		}
	}
	return ctx.onImage && this.getImageId(ctx);
};
})();

一応説明しておくと、画像の上にDIVが置かれるようになりました。もとはNotesだけだったのですが、新しくPersonもこのDIVを使うことになったので、こいつが邪魔になるケースが多くなりました。そこで、このDIVを選択しているときはその下のimgに差し替えると言うパッチです。

とっととGit環境作ってPull Request送れるようにするべきなんだろうな。

[プログラミング]TomblooでdeviantARTからCC情報を付けてポストする

前回の「[プログラミング]TomblooでFlickrのCC情報をつけてポストする」を改造して、deviantARTからポストするときもCreative Commonsの情報を付けるようにしてみました。

2010/5/19 追記

こちらのソースは deviantART Version 7 では動作しません。「[プログラミング]TomblooでdeviantART(Version 7)からCC情報を付けてポストする」をご覧下さい。

前回やった31_Tombloo.Service.extractors.jsの書き換えは、関数置き換えに直しました。やっぱりTomblooの更新毎に書き換えるのは面倒だからね。

以下ソース。前回のFlickr.cc.jsとは衝突するので、万が一使っている人がいたら削除してからにしてね。ダウンロードはCCAppend.jsからどうぞ。

(function() {
Tombloo.Service.extractors.register({
  name : 'Photo - DeviantArt',
  ICON : 'http://st.deviantart.net/icons/favicon.ico',
  URL  : 'http://www.deviantart.com/',
  check : function(ctx){
    return ctx.onImage && 
      ctx.target.src.match('^http://.....deviantart\.(net|com)/..../');
  },
  extract : function(ctx){
    var author = $x('(//div[@class="catbar"]//a[@class="u"])[1]');
    var cc = $x('(//div[@class="cc_license_text"])');
    if (cc) {
      cc = cc.innerHTML
             .replace(/<\/?em>/g, '')
             .replace(/<br>/g, '')
             .replace(/rel="license"/g, '')
             .replace(/target="_blank"/g, '')
             .replace(/  +/g, ' ');
    }
    var url;
    if (ctx.target.src.match('^http://.....deviantart\.net/..../')) {
      url = ctx.target.src
          .replace(/..(..)\.deviantart\.net\/(....)\/[^\/]+\//, 'fc$1.deviantart.com/$2/');
    } else {
      url = ctx.target.src;
    }
    // http://th05.deviantart.net/fs50/300W/f/2009/261/9/0/Pegasus_Manip_by_blommix.png
    // http://fc05.deviantart.com/fs50/f/2009/261/9/0/Pegasus_Manip_by_blommix.png
    return {
      type      : 'photo',
      item      : ctx.title.extract(/(.*) by .+ on deviantART/i),
      itemUrl   : url,
      author    : author.textContent.trim(),
      authorUrl : author.href,
      license   : cc,
    };
  },
}, 'Photo', false);

Tombloo.Service.extractors['Photo - Flickr']['extract'] = function(ctx){
  var id = this.getImageId(ctx);
  return new DeferredHash({
    'info'  : Flickr.getInfo(id),
    'sizes' : Flickr.getSizes(id),
  }).addCallback(function(r){
    if(!r.info[0])
      throw new Error(r.info[1].message);

    var info = r.info[1];
    var sizes = r.sizes[1];

    var title = info.title._content;
    ctx.title = title + ' on Flickr'
    ctx.href  = info.urls.url[0]._content;

    return {
      type      : 'photo',
      item      : title,
      itemUrl   : sizes.pop().source,
      author    : info.owner.username,
      authorUrl : ctx.href.extract('^(http://.*?flickr.com/photos/.+?/)'),
      favorite  : {
        name : 'Flickr',
        id   : id,
      },
      license   : info.license,
      date      : info.dates.taken,
    }
  }).addErrback(function(err){
    return Tombloo.Service.extractors['Photo'].extract(ctx);
  });
};

addAround(
  Tombloo.Service.extractors,
  'extract',
  function(proceed, args, target, methodName) {
    return proceed(args).addCallback(function(ps){
      switch (ps.license) {
      case '1':
        var dd = ps.date.split('-');
        ps.description = '(c) ' + dd[0] + ' <a href="' + ps.authorUrl + '">' + ps.author + '</a>'
        + ' under <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/">CC-BY-NC-SA</a> license.'
        ps.private = false;
        break;
      case '2':
        var dd = ps.date.split('-');
        ps.description = '(c) ' + dd[0] + ' <a href="' + ps.authorUrl + '">' + ps.author + '</a>'
        + ' under <a href="http://creativecommons.org/licenses/by-nc/2.0/">CC-BY-NC</a> license.'
        ps.private = false;
        break;
      case '3':
        var dd = ps.date.split('-');
        ps.description = '(c) ' + dd[0] + ' <a href="' + ps.authorUrl + '">' + ps.author + '</a>'
        + ' under <a href="http://creativecommons.org/licenses/by-nc-nd/2.0/">CC-BY-NC-ND</a> license.'
        ps.private = false;
        break;
      case '4':
        var dd = ps.date.split('-');
        ps.description = '(c) ' + dd[0] + ' <a href="' + ps.authorUrl + '">' + ps.author + '</a>'
        + ' under <a href="http://creativecommons.org/licenses/by/2.0/">CC-BY</a> license.'
        ps.private = false;
        break;
      case '5':
        var dd = ps.date.split('-');
        ps.description = '(c) ' + dd[0] + ' <a href="' + ps.authorUrl + '">' + ps.author + '</a>'
        + ' under <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a> license.'
        ps.private = false;
        break;
      case '6':
        var dd = ps.date.split('-');
        ps.description = '(c) ' + dd[0] + ' <a href="' + ps.authorUrl + '">' + ps.author + '</a>'
        + ' under <a href="http://creativecommons.org/licenses/by-nd/2.0/">CC-BY-ND</a> license.'
        ps.private = false;
        break;
      default:
        if (ps.license) {
          ps.description = '(c) <a href="' + ps.authorUrl + '">' + ps.author
          + '</a> ' + ps.license;
          ps.private = false;
        } else if (ps.type == 'photo') {
          //ps.private = true;
        }
        break;
      }
      return ps;
    });
  }
);

})();

実はエラー処理をサボっているので、Full Viewの映像が取れないとかするとスクリプトエラーになります(苦笑)。ごめんね、ごめんね。あ、githubに入れておけば他の人に弄ってもらいやすいのか…やってみる価値あるかもね。アカウントだけは作ったんだけどなー。

[ネタ]オム子さんブックマークレット

内輪ネタですみません、何となくやっちゃいました。コードを見れば一目瞭然なので解説はなしで…。

javascript:void( (function(){var d = document; var s = d.body.innerHTML.replace(/焼酎/g, '水'); s = s.replace(/ビール/g, '酸素');  d.body.innerHTML = s.replace(/酒豪/g, 'オム子');})());

[オム子する!]

酒豪にお聞きします。ビール、焼酎、サワー、日本酒、ワイン。この5つを翌日にお... - Yahoo!知恵袋」←このページで試してみるといいんじゃないかな。

ネタ元:

なお、当エントリは実在する@irasallyさんとはなにも関係がありません。@irasallyさんって本当に素敵な方なんですってば(力説。

[プログラミング]TomblooでFlickrのCC情報をつけてポストする

2009/09/19 追記

[プログラミング]TomblooでdeviantARTからCC情報を付けてポストする | コマネタ帳」もご覧ください。

LDR+TomblooでTumblrしているんですが、せっかくCreative Commonsな画像をポストしても適切な情報が付加されないという勿体ない状態に。とりあえず、Flickrからのポストの時はCCライセンスの情報をAPIでもらってクレジットをつけてみるようにしました。せっかくなのでソースを晒しておきますが、ほとんどテストしていませんのでご注意ください。

まずは本体ファイル。tombloo/scriptフォルダに保存します。ファイル名はとりあえずFlickr.cc.jsにしています。本当はID番号とURIの関係は別のAPIで取得するべきなんですがサボってます、すみません。

addAround(
  Tombloo.Service.extractors['Photo - Flickr'], 'extract',
  function(proceed, args, target, methodName) {
    return proceed(args).addCallback(function(ps){
      switch (ps.license) {
      case '1':
        var dd = ps.date.split('-');
        ps.description = '(c) ' + dd[0] + ' <a href="' + ps.authorUrl + '">' + ps.author + '</a>'
        + ' Licensed under <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/">CC-BY-NC-SA</a>.'
        break;
      case '2':
        var dd = ps.date.split('-');
        ps.description = '(c) ' + dd[0] + ' <a href="' + ps.authorUrl + '">' + ps.author + '</a>'
        + ' Licensed under <a href="http://creativecommons.org/licenses/by-nc/2.0/">CC-BY-NC</a>.'
        break;
      case '3':
        var dd = ps.date.split('-');
        ps.description = '(c) ' + dd[0] + ' <a href="' + ps.authorUrl + '">' + ps.author + '</a>'
        + ' Licensed under <a href="http://creativecommons.org/licenses/by-nc-nd/2.0/">CC-BY-NC-ND</a>.'
        break;
      case '4':
        var dd = ps.date.split('-');
        ps.description = '(c) ' + dd[0] + ' <a href="' + ps.authorUrl + '">' + ps.author + '</a>'
        + ' Licensed under <a href="http://creativecommons.org/licenses/by/2.0/">CC-BY</a>.'
        break;
      case '5':
        var dd = ps.date.split('-');
        ps.description = '(c) ' + dd[0] + ' <a href="' + ps.authorUrl + '">' + ps.author + '</a>'
        + ' Licensed under <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>.'
        break;
      case '6':
        var dd = ps.date.split('-');
        ps.description = '(c) ' + dd[0] + ' <a href="' + ps.authorUrl + '">' + ps.author + '</a>'
        + ' Licensed under <a href="http://creativecommons.org/licenses/by-nd/2.0/">CC-BY-ND</a>.'
        break;
      }
      return ps;
    });
});

次に31_Tombloo.Service.extractors.jsを変更します。Tomblooを更新すると変更が上書きされるので避けたいのですが、この中で呼んでるgetInfo APIでライセンス情報が取れるので、とりあえずこちらを変更しました。いっそextractメソッド丸ごとFlickr.cc.jsに持ってくればいいのかな?

  {
    name : 'Photo - Flickr',
    ICON : models.Flickr.ICON,
    // 中略

    extract : function(ctx){
      var id = this.getImageId(ctx);
      return new DeferredHash({
        'info'  : Flickr.getInfo(id),
        'sizes' : Flickr.getSizes(id),
      }).addCallback(function(r){
        if(!r.info[0])
          throw new Error(r.info[1].message);
        
        var info = r.info[1];
        var sizes = r.sizes[1];
        
        var title = info.title._content;
        ctx.title = title + ' on Flickr'
        ctx.href  = info.urls.url[0]._content;
        
        return {
          type      : 'photo',
          item      : title,
          itemUrl   : sizes.pop().source,
          author    : info.owner.username,
          authorUrl : ctx.href.extract('^(http://.*?flickr.com/photos/.+?/)'),
          favorite  : {
            name : 'Flickr',
            id   : id,
          },
          // ここから追加
          license   : info.license,
          date      : info.dates.taken,
          // ここまで追加
        }
      });
    },
  },

これでFlickrからポストすると、Descriptionに例えば「(c) 2008 iyoupapa Licensed under CC-BY-SA.」といった文字列が自動で設定されます。表記としてこれで正しいのか、全く自信がないのですが何もないよりいいんじゃないかな。

できればrel="license"とかRDFを認識した方が適用範囲は広くなるんですが、意外と機械的に適用できない(一部分だけに適用、とかReblogは除く、とか)ケースが見受けられるので、比較的確実なFlickrに絞ってみました。RDFの適用範囲とか調べないとダメですね。

あとは過去のポストのライセンスを確認して、CC情報をつけるか削除(orプライベート)するかしないと…手作業じゃ無理なんでなんか作るしかないですね。そこまでするならTumblrヤメレってのは無しの方向で。

[C#]DataGridViewCheckBoxCellにラベルを表示する

DataGridViewCheckBoxLabelCellC#.NET Framework 限定エントリで申し訳ないです。ツール類を作るのに DataGridView が便利だったりするんですが、DataGridViewCheckBoxCell はチェックボックスしか表示されません。せめてラベルでも表示できれば少しは便利…と言うより列が減らせるな、というクラス DataGridViewCheckBoxLabelCell です。

2012/05/08 追記

gistに登録しました。(DataGridViewCheckBoxLabelCell)

使い方

  1. namespace が AdvancedDataGridView なのは Mark Rideout さんの TreeGridView に組み込んでいたからです。適宜修正してください。
  2. DataGridView のプロパティで、列のクラスに DataGridViewCheckBoxLabelColumn を選びます。
  3. Cell を DataGridViewCheckBoxCell にキャストして、 LabelText プロパティにラベルを設定します。

バインドには対応してないんです、ごめんなさい。

ライセンス

FreeBSD ライセンスと同じです。

これって意味あるの?

このクラスの意味は「セルに自力でチェックボックスを描画するサンプル」です。後は俺の自己満足w。

なお、.NET Framework のバージョンは 2.0 で確認しています。

[ネット]Twitter Botをいじってもらいました。

As a Futurist...」さんで開発オフのときのソースをいじってくれました。私はWindowsでやっていたのでCPANの使い方を端折りましたが、UbuntuでのCPANインストール手順がしっかりまとまっていていい感じです。しかも文字コードの処置もちゃんとしていただいてます。確かにあの時は日本語を通していませんでした…陳謝。

第2弾でPostをIM経由にしています。この後どう料理が進むのか興味があるのでLDRにポチッと登録しておきました。で、せっかくなんだからトラックバックしてくれてもいいのになぁ。こっちがトラバを受け取れていないってオチじゃないと思うけど。

前回の開発オフをサボってしまったため、次のネタを用意したいところですが…思いついたのが「キャズムの向こうの人たちにRSSやSBMを使ってもらう」という意味不明なテーマ。さて、どうなりますやら。

Refs:

[プログラミング]ついカッとして @JHWHokkaido を作った。

2/23~2/24の荒天は凄かったですね。被害に遭われた方々にお見舞い申し上げます。

幸いにして俺は外出する予定もなく、いつも通りに過ごしていました。とはいえ、 JR の状況は @JRHokkaidoSap で随時チェック。「これなら JR 以外の情報も欲しくね?」と思い始めまして、勢いで北海道の高速道路状況を配信する @JHWHokkaido なる物を作ったのでした。 JH+HighWay で JHW などと考えていたのですが、 JH なんて既にねぇよ、バカだね俺ヽ(`Д´)ノ 。

今回はダイスロールボットのソースを流用したので、「@」を投げると最新状況を「@」で返信してくれます。調整不足で5分に1回 Update しているようですから、 Follow しないで「@」を使うのも手かも知れません。

情報のフォーマットが汚いのですが、どうすればいいか思いつきません。ご意見募集中ですm(_ _)m。

2008/2/26 追記

@hadzimmeさんから指摘していただいたので、方面毎にポストを分けました。道央道(旭川方面)、道央道(室蘭方面)、札樽道、道東道の別です。深川留萌道は情報が出てくるのか不明です><。旭川紋別自動車道は対象外です><。

「@」での問い合わせの時に「道央」とか「樽」と付けてあげると、一致する高速の分だけ返信します。該当する高速が無いときは全道路分返しますので諦めてください。

続きを読む

[プログラミング]Twitter Botの続き

[プログラミング]北海道開発オフでTwitter botを作ったよ | コマネタ帳」での残務をこなします。かなり日数が空いてしまいましたが、少しは進捗したところをお見せしないと、前回の記事をブックマークしたりはてなスターつけたりして頂いた値がなくなります><。Perl用語がかなり不自由なんで、突っ込みどころ満載のエントリですが良しなにお願いします。

続きを読む

[プログラミング]北海道開発オフでTwitter botを作ったよ

第1回の北海道開発オフ部に参加してきました。オフの状況は別途レポートするとして、作っていたサイコロ振りボットがここまでできたよ、という「作業報告」をしたいと思います。あれだけ黙々と作業してて、何もできてないってのもあれなんで。

今回はユーザーと対話できるBotを考えていました。内容はともかく、とりあえずテンプレートとして使える方向を目指します。

2008/02/16 追記

[プログラミング]Twitter Botの続き | コマネタ帳」に続きを書きました。

続きを読む

skin presented by myhurt : BLOG | SKIN
  
copyright © 2005 コマネタ帳(旧) some rights reserved. Powered by FC2ブログ