Twitter→はてなブックマーク 連携機能用ブックマークレット

Twitter のつぶやきからブックマークできる、Twitter との連携機能をリリースしました - はてなブックマーク日記 - 機能変更、お知らせなど の機能を使えるブックマークレットを書きました。
T2B!ブックマークレットのリンクが書けないので、登録後に?までを削除してください)

javascript:(function(){if(m=prompt()){w=window.open('','_blank','width=0,height=0');f=w.document.createElement('form');f.setAttribute('action','http://twitter.com/statuses/update.xml');f.setAttribute('method','POST');f.setAttribute('accept-charset','utf-8');i=w.document.createElement('input');i.setAttribute('type','hidden');i.setAttribute('name','status');i.setAttribute('value',m+'%20B!%20'+location.href+'%20'+document.title);f.appendChild(i);w.document.documentElement.appendChild(f);f.submit();w.onunload=function(){w.close();}}}())

Twit! ブックマークレットの Google Chrome 対策 - 徒なる研究あるいはイアトロ化学者 をちょいと書き換え。
コメント必須なのね。URL の後に文字列が付くのは OK。


はてブツイート : はてなブックマークをTwitterに投稿 が最近は原因不明の投稿失敗を頻発させてるんだよなー。Twitter API は 200 OK を返しているのだが、投稿できていないという謎の現象。

動画サムネイルの表示とか iTunes アフィリエイト貼り付けとか JavaScript でやったメモ

ChordWiki に加えた機能をメモっとく。

YouTubeニコニコ動画のサムネイル画像を JSONP で表示

動画埋め込みを止めて外部リンクが文字だけだと寂しいので賑やかしにサムネイル画像だけ表示したい。API を使うのだが、自サーバの負担は増やしたくないので JSONP を使う。
YouTube簡単に画像 URL を作る方法もあるみたいだけど、実際に使われている URL は違うので、律儀に API を呼ぶ。

<img id="ytthumbnail" class="thumbnail"/>

という空の img タグを置いといて

<script type="text/javascript" src="http://gdata.youtube.com/feeds/videos/(ビデオID)?alt=json-in-script&callback=ytthumbnail"></script>

JSONP を呼び出す。
コールバック関数はこんな感じ。

function ytthumbnail(data){
  document.getElementById("ytthumbnail").src=data.entry.media$group.media$thumbnail[0].url;
  document.getElementById("ytthumbnail").alt=data.entry.title.$t;
  document.getElementById("ytthumbnail").title=data.entry.title.$t;
}

ニコニコ動画の場合は APIXML しか用意されていないので YQL を使う。

<img id="nicothumbnail" class="thumbnail"/>
<script type="text/javascript" src="http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D%22http%3A%2F%2Fext.nicovideo.jp%2Fapi%2Fgetthumbinfo%2F(動画ID)%22&format=json&diagnostics=false&callback=nicothumbnail"></script>
function nicothumbnail(data){
  document.getElementById("nicothumbnail").src=data.query.results.nicovideo_thumb_response.thumb.thumbnail_url;
  document.getElementById("nicothumbnail").alt=data.query.results.nicovideo_thumb_response.thumb.title;
  document.getElementById("nicothumbnail").title=data.query.results.nicovideo_thumb_response.thumb.title;
}

例:magnet (みなと(流星P) feat.巡音ルカ・初音ミク) - ChordWiki : コード譜共有サイト

iTunes Store へのアフィリエイトリンクを自動生成

Amazon アソシエイトの売上が既存サイトに比べて著しく悪いのでアフィリエイト先を増やしたい。リンクシェアが iTunes Storeアフィリエイトをやっているのだが、リンク生成するにはいちいちリンクシェアのサイトに行かないと作れない。そこで iTunes Store Web Service Search API (PDF) を使う。

404 Blog Not Found:Ajax - iTunes Store 検索

を参考にした。というかパクった。
コードは汚いままなので転記しないが、要点としてはここ。

var a = d.createElement('a');
a.href='http://click.linksynergy.com/fs-bin/click?id=(アフィリエイトID)&offerid=94348.1'+json['trackId']+'&type=2&subid=0';

これが正しいのか分からない。時々リンクが繋がってないようだ。パラメータの意味をもっと検証した方がいいかも。
Amazonウィジェットに比べると検索が厳密なのでヒットしないことも多い。そして現在まで売上はゼロ。
例:Just Be Friends (Dixie Flatline feat.巡音ルカ) - ChordWiki : コード譜共有サイト

ChordWiki 商用配信化と JASRAC の見解

3周年を迎えた ChordWiki : コード譜共有サイト 〜無料の歌詞とコードをシェアしよう を、非商用配信区分から商用配信区分(広告あり)に変えた。
JASRAC に支払う利用料が、《10,000円/年》から《収入の3.5%(最低5,000円/月)》になる。
その過程で分かったことがあるのでメモしておく。

YouTube 動画の埋め込み(embed)

YouTubeJASRAC と楽曲利用許諾契約を結んでいるわけだが、その動画を自サイトに埋め込んで表示するのは白か黒かグレーか、つまり自サイトと JASRAC の間に契約が必要なのか、よく分からなかった。
今回 JASRAC 担当者とのやり取りで発覚したことは、

  • 非商用配信区分のサイトであれば、YoutubeJASRAC との間の許諾契約の範囲内
  • 商用配信区分であれば、個別に手続きが必要

じゃあ、そもそもどちらの区分でも JASRAC と手続きしていないサイトはどうなの? というのは分からない。だが普通に考えると非商用であれば「YoutubeJASRAC との間の許諾契約の範囲内」となっているのではないだろうか。


ちなみにインタラクティブ配信使用料早見表によると、「音楽を主とした利用(リスニング用、カラオケ用、着信音等)」でも「可視的な利用(歌詞テキスト、楽譜等)」でもストリーム形式なら「月間の情報料及び広告料等収入の3.5%・最低使用料(月額)5,000円」で変わらない。
だが、上記の許諾契約はあくまでも楽曲に関するものであり、演奏は含まれない。自分で演奏して up されたものだけが OK で、PV などが使用されると黒かグレーなので、埋め込み使用は止めて外部リンクとした。(非商用配信区分のサイトであれば、YoutubeJASRAC との間の問題と解釈できるかは微妙か)

歌詞のコピー禁止、印刷禁止

印刷に関しては非商用配信の時から、CSS を使って歌詞が印字されないようにしていた。

@media print{
	span.word {
		visibility:hidden;
	}
}

これで良いらしい。


コピーについては今回、

  • 商用配信区分の場合はコピーも禁止にしてください。

と指摘された。
画像化は技術的に難度が高い。かといって右クリック禁止は、Firefox では alert の後ちゃっかりコンテクストメニューが出たりする経験があって疑問だったが、↓で上手く行った。

<div onCopy="alert('コピーはできません。'); return false;" onCut="alert('コピーはできません。'); return false;">

IEFirefoxSafariGoogle Chrome で、普通にはコピーできない。(Opera は試していない。)
これで許諾も通った。

Android のバーコードリーダーから直接 MediaMarker に登録できたからまとめないで書く

http://souzou.fuzimoto.info/2009/08/iphonemediamarker.html だけど、AndroidHT-03A)なら無料アプリ QRコードスキャナー で出来る。

起動したら「MENU」ボタンで「設定」を呼び出して、「カスタム商品サーチURL」を開く。
設定する URL は想造ノートさんが書いているのとほぼ同じ。

http://mediamarker.net/u/ユーザーID/search9?cat=9&srh=1&auto=1&q=%s

%s に、スキャンしたコードが入る。

で、書籍の上段バーコードをスキャンして、

右下の「カスタムサーチ」を押すと、メディアマーカー のページが開き、登録完了する。最初だけ MediaMarker へのログインが挟まる。


ちなみに「商品検索」で Google 検索、「書籍を検索」で Google ブック検索、「書籍の内容を検索する」で Google ブック検索内の該当書籍のサーチボックスが出る。
Amazon に飛びたいなら、カスタムサーチ URL にそれっぽいのを入れれば OK な訳ね。

Twitter Echo Bot サービス終了

9ヶ月前に停止を予告したTwitter Echo Bot ですが、完全に終了させました。


理由は、@train_kanto が、スパムだか bot だか分からない投稿で溢れたこと。
某所から取得する情報の自動投稿だけでは遅いことが分かっていたので、他の人からの投稿を受け付けるために始めた機能だが、スパムに利用される危険性は懸念していた。ブロックすればいいと考えていたが、本格的に悪用されたら間に合わないことは分かっていた。そして実はブロックが効かないことも最近になって把握していた。
しかし幸いなことに最近までは順調に機能していた。
少し前から ReTweet が使われ出して、反映されるようになっていたけど、コメント付きの RT なら有意義であると考えて、放置した。
あと @fuba_recorder と会話を始めてしまったこともあったけど、その内収束した。
しかし 8/9頃から無意味な英文や @だらけの投稿が連続ポストされる事態に陥り、フォロワーのタイムラインを荒らしてしまっていた。(こういうのとかこういうの
旅行中だったので対処を見送っていたのだが、目に余ったので、HT-03A から ConnectBot で ssh ログインして止めた。


http://twicco.jp/ と同じ機能だったのだけど、あちらは対策をしているのだろうか。


対策を施して再開するつもりはない。ハッシュタグを使う。
Train (Kanto,Japan) (@train_kanto) | Twitter
booknews (@booknews) | Twitter


ハッシュタグの選び方は悩みどころ。
最初 #train_kanto にしてみたが、#train_kansai の方が検索で有効にならなくて、あちこち見てみると、アンダースコア入りのハッシュタグが無いことに気付く。どこかで定義されているのかどうかは不明だ。そこで #TrainDelay にしてみる。普通の英語なので使われているかと思ったが、ヒットしない。海外の電車は遅れるのが普通だから皆気にしないという説は本当なのかな。仮に他言語で使われるようになったとしても、ハッシュタグはリアルタイム性が肝なので、大して問題にならないのではないかと推測。
#booknews は台湾の人が使っている。#shuppan を採用。#publishing なんてのも使われているけど、ここはローマ字で。
検索時に言語指定できることや、ハッシュタグ自体の将来的な多言語対応などもあるが、結局は他の人にも使ってもらうことが重要。判断が難しいので当面はこれで様子を見る。

HT-03A にインストールしたアプリケーション

購入してから10日ほど。ぼちぼち使っている中で今現在入ってるアプリ。

Simeji

これは必須と言っていい。T9入力に慣れてしまったので iWnn のケータイ入力には耐えられないところだった。
OpenWnn版にしている。

TwitterRide

Twitter クライアントはこれ。
Twidroid よりもスクロールや更新時の動作が良いような気がする。
Twidgit Lite のようにウィジェットとして使うのは利点が分からない。

はてなB Lite

ブラウザから共有機能でブクマするのに使う。

Steel

標準ブラウザ(Mobile Safari)の動作で不服な点として

がある。
この二つの代替ブラウザではブックマークレットが使えるが、標準ブラウザにはある「リンク先をブックマークに登録」が無くて結局使うのが面倒。Opera はまた勝手が違って使いにくい。
標準ブラウザでブックマークレットが使えるようになるのに越したことはないが、Android では「共有(Intent)」を使うのが主流であるようだ*1Twitterはてなブックマークも、標準ブラウザから「ページを共有」で上記のアプリに投げて使うことになりそうだ*2

Task Manager

アプリを明示的に終了できないのがちょっと気持ち悪いので使ってみる。慣れるのかもしれないけど。

朝日新聞

様子見。

Qik

QRコードスキャナー

Toggle Setting

そのうち使うかな。


プリインストールアプリの中では、羅針盤の星座モードが面白い。GPS地磁気センサーと加速度センサーを使い、機体を向けた方向の星座が表示される。


あとは Tumblr を使いたいな。今のところ http://www.tumblr.com/iphone にアクセスしてる。画像を拡大して戻った時にページ先頭に飛んでしまうのが難点だ。

*1:ただし Java での開発は敷居が高い。android-scripting に期待か。

*2:ただし標準ブラウザからは URL しか渡されていないように見える。カメラで撮った写真を、メールや Twitter アプリに「共有」すれば写真そのものが渡されるので、ページタイトルやコンテンツも投げられそうなのだが。

グーグル携帯 HT-03A を買ったので、iモードのメールを自動転送 (追記あり)

買ってしまった。
文字入力のスピードがまだまだ上がらないけど、概ね満足している。


目下の難点が、Gmail から 友人の携帯へ送るメールが、迷惑メール対策で撥ねられてしまう点だろう。
アドレス変わりましたメールを送って、撥ねられた相手には iモードから送り直したが、安心は出来ない。
iモード契約を残して(315円/月)、imode.net も契約したので(210円/月)、読み書きは出来るのだが(スマートフォン向けページを使えば Firefox からも利用可能)、いちいちアクセスするのは面倒だ。
自動転送機能くらい付けてください>DoCoMo


そこで、自前で自動転送することにした。
以下のスクリプトを cron で実行する。
Cookie を取得しながら URL 転送を繰り返す。ああ面倒くさい。Mechanize とか使うといいのかな。
最後は、iモード.net の転送機能は使わず、メール本文のページを HTML のまま送信している。
メール送信周りはさくら仕様。


(7/24追記)
imode.net だが、ログイン通知メールとかいうのが毎回飛ぶ。
それが imode.net には表示されないので、消せない。
実機で受信しないといけない。普通のメールも含めて、imode.net はメールサーバ上にあるんじゃなくてただのクライアントであり、ケータイで受信して初めてサーバから消える。
そしてメールが溜まるとログインできなくなる。
このスクリプトが起動する度にログイン通知メールが蓄積されるので、頻繁にチェックしていると使い物にならない。


ログインをキープする 新着i の使用を推奨します。

#!/usr/local/bin/ruby

require 'cgi'
require 'net/https'
require 'nkf'
require 'net/smtp'

docomoid="xxxxxxxx"
docomopass="xxxxxxxx"
forwarding_address="xxxxxxxx@gmail.com"

def send_mail(mailto,mailbody)

  mailserver="xxxx.sakura.ne.jp"
  maildomain="xxxx.sakura.ne.jp"
  mailid="xxxx@xxxx.sakura.ne.jp"
  mailpass="xxxxxxxx"
  mailfrom="xxxx@xxxx.sakura.ne.jp"

  Net::SMTP.start( mailserver, 25, maildomain, mailid, mailpass, :login ) {|smtp|
    smtp.send_mail <<EOM, mailfrom, mailto
From: #{mailfrom}
To: #{mailto}
Subject: Forwarding from imode
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: Quoted-printable

#{mailbody}
EOM

  }

end


response=""
https = Net::HTTP.new('imode.net', 443)
https.use_ssl = true
#https.ca_file = 'base64.cer'
#https.verify_mode = OpenSSL::SSL::VERIFY_PEER
#https.verify_depth = 5
https.start {

  param="HIDEURL="+CGI.escape("?WM_AK=https%3a%2f%2fimode.net%2fag&path=%2fimail%2fm%2fsmarttopimobile&query=")
  param << "&LOGIN=WM_LOGIN"
  param << "&WM_KEY=0"
  param << "&MDCM_UID="+docomoid
  param << "&MDCM_PWD="+docomopass

  response=https.post( "/dcm/dfw", param )
}

cookie=response['Set-Cookie'].split(',').join(';')
/WM_IW_INFO_PA=([^;]+);/=~response['Set-Cookie']
wm_iw_info_pa=$1
#p wm_iw_info_pa
loc=response['Location'].gsub(/^https:\/\/imode\.net/,'')

https.start{
  response=https.get( loc, "Cookie"=>cookie) #ag
}

cookie=response['Set-Cookie'].split(',').join(';')
/WM_IW_INFO=([^;]+);/=~response['Set-Cookie']
wm_iw_info=$1
#p wm_iw_info
loc=response['Location'].gsub(/^https:\/\/imode\.net/,'')

https.start{
  response=https.get( loc, "Cookie"=>cookie) #smarttopimobile
}

loc=response['Location'].gsub(/^https:\/\/imode\.net/,'')

https.start{
  response=https.get( loc, "Cookie"=>cookie) #smart
}

cookie=response['Set-Cookie'].split(',').join(';')
/pwsp=([^;]+);/=~response['Set-Cookie']
pwsp=$1
#p pwsp
loc=response['Location'].gsub(/^https:\/\/imode\.net/,'')

https.start{
  response=https.get( loc, "Cookie"=>"pwsp="+pwsp+"; WM_IW_INFO="+wm_iw_info+"; WM_IW_INFO_PA="+wm_iw_info_pa) #smart?func
}

response.body.split("\n").each{|line|
  if /<td><span class="unread"><a href="\.\/([^"]+)">[^<]*<\/a><\/span><\/td>/=~line
    loc=$1.gsub('&amp;','&')
    https.start{
      response=https.get( "/imail/m/imobile/acgi/"+loc, "Cookie"=>"pwsp="+pwsp+"; WM_IW_INFO="+wm_iw_info+"; WM_IW_INFO_PA="+wm_iw_info_pa) 
    }

    send_mail(forwarding_address, response.body)
  end
}