GitHubにはissueっていう、tracでいうticketと同じような懸案リストを登録し管理する機能があります。
今回は、このissueとファイル修正時のコミットを関連付けして、さらにハイレベルなタスク管理として利用しちゃうためのテクニックを紹介します。 Continue reading
GitHubにはissueっていう、tracでいうticketと同じような懸案リストを登録し管理する機能があります。
今回は、このissueとファイル修正時のコミットを関連付けして、さらにハイレベルなタスク管理として利用しちゃうためのテクニックを紹介します。 Continue reading
別にどうでもいいことなんですけど、どうでもよくないかも知れないけど。笑
Twitter で、 を入力したらスペースに変換(正確には、そのまま。笑)されて表示されているのを発見して、ほんのちょっとだけ試して見ました。
入力したテキストは以下。
¥ とか < とか » とか とかエスケープされてない?
以下はtwitter for Macでの入力結果。

そして、以下の画像は twitter.com 上での表示。

で以下はtwitter api経由での表示。
というわけで、よくわかんないけど、HTML実体参照がエスケープされないということを発見。
リスクがあるのか無いのかは、忙しくて調べる余裕が無いのでだれか教えてください。
最近、遅ればせながらinstagram がお気に入りなのですが、この写真のギャラリーとして表示するためのWordPressプラグインをつくろうかなーっと思ってます。
しかし、instagramのAPIを取得するには、メールフォームで問い合わせが必要そうなので、プラグイン作って配布ってのはムリかな?と思ってました。
http://instagram.com/developer/
しかし、サードパーティーのAPIを使えば、そのユーザーが投稿した写真の情報などをJSONデータで取得できることがわかりました。
なんの会社かよくわかりませんが、エライ!
http://www.heroku.com/
ただし、このJSONデータを取得するには、instagramのユーザーIDを取得する必要があるのですが、これはパーマリンクのURLからHTMLを取得してDOMを掘って…という処理が必要です。
というわけで、これらを処理するPHPのクラスを作りました。
このクラスの使い方は以下のような感じです。
$ins = new instagram(); $uid = $ins->getUID($url); // User ID var_dump($ins->getJsonURI($uid)); // JSON URL var_dump($ins->getAtomURI($uid)); // Atom URL
あとは、このJSONを feile_get_contents() などでとってきて、json_decode() しでギャラリーを生成みたいな感じです。
WordPressプラグインはおいおい作ります。
Facebookではlikeボタンをクリックした時などにクローラーが攻めこんできてコンテンツをキャッシュします。
そのため、タイトルなどを後から修正しても、修正結果が反映されません。
しかし、Facebook謹製のURLリンターというツールでURLを送信するとクローラーがもう一度来てくれて、キャッシュを再生成してくれます。
そこで、WordPressのsave_postでフックして、URLリンターにURLを送信するプラグインを作りました。
この数日facebookについて勉強してるんですが、OGPについていろいろ調べてるうちにWordPressのWP-OGPプラグインが不十分というか怪しい気がするので、OGPについて私なりに調べてみたことを書きます。
ていうか、誰か詳しい人は教えてください。お願いします。
OGPについては詳しく解説しませんので、Google先生などに聞いてください。
og:typeの値はWP-OGPプラグインでは、全てのページがarticeで固定になっているようですが、違うような気がします。
まず、投稿の場合、これはarticleでいいと思われます。一時的な情報はarticleとすべしとのことなので。
しかし、サイトのトップページでは、以下のような感じになるような気がするんですけどどうでしょう?
あと、固定ページの場合。
これもarticle固定ではおかしい気がします。
たとえば、このサイトではWordPressのプラグインを配布しているのですが、それらのプラグインのページでは、productとなるべきではないのかな?
プロフィールのページがもしあるならprofileとすべきじゃないかと。
facebookのAPIでは、”イイネ”ボタンをクリックしてくれたユーザーに対して、そのページの更新をお知らせすることができるようです。(試せてません…)
しかし、ブログの記事はファンの対象にはならない一時的なものであるため、articleを指定するべきであり、articleにはこの機能が働かないそうです。
http://d.hatena.ne.jp/amachang/20110117/1295233078
なので、例えば企業サイトの製品紹介のページを更新した場合に、せっかくそれをお知らせするための素敵な仕組みがあるのに、それを使えないのは悲しくないですか?
(だからといって、なんでもかんでもarticle以外にして呼び戻し機能を使うのは、スパムって言われちゃう可能性があります。)
根本的にWP-OGPではfb:appidと出力されていますが、fb:app_idの間違いのようです。
あと、fb:admins と fb:ap_id はどちらか片方だけを使用するべきのような気がします。 両方でもいいみたいです。
fb:adminsorfb:app_id– A comma-separated list of either Facebook user IDs or a Facebook Platform application ID that administers this page. It is valid to include bothfb:adminsandfb:app_idon your page.
facebookの説明によると、50個以上”いいね”をゲットすると”og:title”が固定され、10,000以上”いいね”をゲットすると、og:typeは固定されるようです。
(キャッシュされて、修正しても反映されないようです。)
You can update the attributes of your page by updating your page’s
<meta>tags. Note thatog:titleandog:typeare only editable initially – after your page receives 50 likes the title becomes fixed, and after your page receives 10,000 likes the type becomes fixed. These properties are fixed to avoid surprising users who have liked the page already. Changing the title or type tags after these limits are reached does nothing, your page retains the original title and type.
以上、私なりに調べた結果を書いたのですが、OGPに関連するAPIとかの挙動については、わからない事だらけです。
詳しい方は、ぜひ教えてください。お願いします!
現在、WordPressをfacebookのアプリとして動作させるためのプラグインを作ってるのですが、コンテンツ部分の横幅や高さに関するメモ。
facebook アプリは、アプリとして登録するとiframeで外部サーバーのコンテンツを表示しています。
iframeなので、好き勝手に横幅を設定しちゃとスクロールバーが出てカッコ悪いので、CSSなどで横幅を予め合わせておく必要があります。
わかりにくいのですが、アプリは単独で開かれる場合とタブで開かれる場合があって、それぞれ最大の横幅が違います。
アプリ側のbody要素のmarginとpaddingの調整もお忘れなく。
高さもコンテンツが縦長になると縦スクロールが出てみっともない事になってしまいますが、これはfacebookのJavaScript SDKで親ページのiframeの高さを変更するためのAPIが提供されています。
以下はAPIを使った高さ調節の例で、body要素の終了タグ直前にコピペしてください。
jQueryを使ってます。
FB.Canvas.setAutoResize() で自動的に高さが調整されるのですが、サイトによっては FB.Canvas.setSize() も紹介されていることが多いようです。
個人的には、FB.Canvas.setSize() のほうは他のJavaSCript でコンテンツ領域の高さが変わる場合に、いちいちコールする必要があったので、使いにくいと思いました。
先日、このサイトを軽くリニューアルしました。
そのリニューアル作業の中で、ソーシャルボタンを設置しなおしたのですが、それ以来Google Analyticsが挙動不審になりました。
具体的には以下のような現象です。
など。
これらはどうやらfacebookのいいねボタンとGoogle Analytics とIEの組み合わせで起こるバグのようです。
http://seoblog.seosearch.biz/?eid=45
なお、この件に関しては複数のブログで記事にされているようですが、対処方法に微妙に間違いがあるものがちらほらありました。
たとえば、以下のような感じ。
http://www.myu-zin.com/webridge/archives/687.html
このページに記載されている方法ではクエリー文字列を無視するだけなので、やたらページビュー数が高いページが出てきてしまいました。
twitterで指定したユーザーの最新のツイートをfacebookのウォールに投稿するPHPスクリプトを作りました。
このアプリのために作りました。
ただーし、実際にこれを動かすには、
という一見簡単そうだけど、めっちゃめんどくさい手続きが必要です。
以上が完了したら、以下のスクリプトの”YOUR …”の部分を修正して Cron でぶん回してください。
twitterのユーザー名は、コマンドライン引数で渡すようになっています。
あと、require してるファイルは facebook のPHP 用の SDK です。
Cronには、以下のように渡したほうが幸せになれると思います。
*/10 * * * * export LANG=ja_JP.UTF-8; /usr/bin/php /path/to/cron.php twitter_user
初のfacebookアプリを作りました。
このアプリは東京電力の電力需要のデータを表示するアプリです。
いいねボタンをクリックしてもらえば、最新の需要データを受け取ることができます。
とりあえず、facebookアプリ開発のいい練習になってくれました。
先日、twitter API の仕様が変更になって、基本認証が使えなくなった。
そのため、以下の記事のスクリプトが動かなくなった。
そこで、oAuthに対応したものをご紹介。
Twitterの検索メモに登録されたキーワードのリストを取得して、タイムラインを検索し、マッチしたものを公式リツイートする。
oAuth認証を行うには以下の情報が必要なので、アプリケーション登録申請を行う。
実用! PerlでコマンドラインからTwitter投稿(OAuth対応) – perl-mongers.org
以下のような感じ。
13行目〜17行目を書き換えること。
あとは、Cron等に登録して使用する。
#!/opt/local/bin/perl -wT
#binmode(STDOUT, ":utf8");
use strict;
use Encode;
use Net::Twitter;
use URI::Escape;
use LWP::Simple;
use XML::DOM;
# Config
my $user = ''; # Twitter のユーザー名
my $key = ''; # Consumer key
my $secret = ''; # Consumer secret
my $token = ''; # Access Token
my $tsecret = ''; # Access Token Secret
my $lang = 'ja';
my $api = 'http://search.twitter.com/search.atom';
# do not need to edit
my $max_length = 140;
my $home;
if (-d $ENV{'HOME'} && $ENV{'HOME'} =~ /^(\/.+)$/) {
$home = $1;
}
my $log = $home.'/.twitbot.txt'; # 最新のIDを保存して次回以降はこのID以下は無視
if (!-e $log) {
open (OUT, ">", $log);
close(OUT);
}
my $max_id = 0;
open (IN, "<", $log);
my $n = <IN>;
if ($n) {
chomp $n;
$max_id = $n;
}
close(IN);
# connect to twitter
my $twt = Net::Twitter->new(
traits => [qw/API::REST OAuth WrapError/],
consumer_key => $key,
consumer_secret => $secret
);
$twt->access_token ($token);
$twt->access_token_secret($tsecret);
my $sch = $twt->saved_searches();
my %posted;
my $since = $max_id;
foreach (@$sch) {
my $k = uri_escape_utf8($_->{query});
my $url = $api.'?show_user=true&q='.$k.'&lang='.$lang;
my $atom = get($url);
my $parser = new XML::DOM::Parser;
my $doc = $parser->parse ($atom);
my $nodes = $doc->getElementsByTagName ("entry");
for (my $i=0; $i<$nodes->getLength; $i++) {
my $node = $nodes->item($i);
my $txt = getvalue($node, 'title');
my $id = getvalue($node, 'id');
if ($id =~ /([0-9]+)$/) {
$id = $1;
} else {
die ('can not get id');
}
if ($max_id < $id) {
$max_id = $id;
}
# 以下に該当するものはRTしない
# 自分の投稿
# RT(スペース)が含まれる投稿
# @が含まれる投稿
# すでにRTした投稿
# ログに保存されたIDより古い投稿
if ($txt !~ /^$twitter_user/ && $txt !~ /RT\s/ && $txt !~ /\@/ && !$posted{$id} && $since < $id) {
$posted{$id} = 1; # 重複投稿しないためのフラグ
eval {$twt->retweet($id)};
if ($@) {
warn "update failed because: ".$@."\n";
}
}
}
}
open (OUT, ">", $log);
print OUT $max_id;
close(OUT);
exit;
sub getvalue {
my $node = shift @_;
my $tag = shift @_;
my $n = $node->getElementsByTagName($tag)->item(0);
return $n->getFirstChild->getNodeValue;
}