git/svn連携も可能なプロジェクト管理 Springloops

moongiftさんで見かけて触ってみたけど、見た目もよくって、ぱっと見必要な機能が必要なだけある感じです。
仕事でもredmineをさっぱりにして使っているのですが、実際小規模(つか、自分しか使ってない)なので、このくらいのさっぱり感があるとうれしい。

・git/svn連携が簡単
・ドラッグ&ドロップでチケットを移動させたりできる
・今はRCで無料
・redmineのデフォルトよりはおしゃれ
・ちょいレスポンスが遅い
・ローカルでなくて、カスタマイズしなくていい場面があるなら良い。

Springloops 2.0 Release Candidate

Finderのツールバー

わお!
こんなところに機能?を追加できるのねー。いいね。
右クリックしたメニューのサービスのところにしかできないと思ってた。

110214-0003.jpg

左から以下のような機能です。
 このディレクトリをTextMateで開く
 このディレクトリをTerminalで開く
 このディレクトリに空ファイルを作る

探してないけど他にも便利なのがあるのでしょうね。

Mac OS X Finder Toolbar Scripts for Textmate, Terminal, and Touch. — Manas Tungare

instagramの画像をだらだら眺めるものを作ってみた

最近やっとiphoneを手に入れて、instagramなるおしゃれカメラアプリなんかを眺めたりしてるわけですが、このinstagramは画像の流れる速度がとっても早い上に、PCから一覧で見ることができません。
そこでだらだらっとinstagramの画像を眺めるページを作ってみました。

という、話はちょ〜後付なんですが、
python+GAEの勉強ということで作ってみました。
(instagramネタとしてはだいぶ遅れた話だとは思います、最近iphone買ったので許して・・・)


instagramの画像をだらだら眺める

眺めるというか、流れるって感じですが。
ほっとくとえらいことになってます。

動作としては、gaeのタスクでtwitterからinstagramのURL付きのついーとを拾って、そのURLから画像を取得して、サムネイル化してDBに入れて、あとは適当に表示、です。
ログを見てると「You have been rate limited. Enhance your calm」ってtwitterによく怒られてます。

■instagramをより楽しみたい方は他にも色々サービスがあるみたいなので以下をどうぞ。

iPhoneアプリ【Instagram】をより楽しむためのWebサービスまとめ – NAVER まとめ

——

twitterに怒られまくりで流れが止まりますなぁ・・・。

nginxでwordpressを高速化

この記事(WordPressを100倍速くする! MySQLの調整やnginx proxy cache | KRAY Inc)をみて、触りたかったけど放置していたnginxがもう我慢できなーいになってしまいましたケロッグ。

Web Server Survey | Netcraftによると2011年1月のウェブサーバのシェアはapache 59.13%、iis 21.00%、nginx 7.50%となっています。
なかなか元気です。

というわけで、まずはこのブログをnginx上で動かしてみました。
nginx+php(fastcgi)+nginx cache+mysql+wordpressです。
簡単にabで計測してみたところは以下の通り。

Requests per second:
|~apache|~nginx(キャッシュなし)|~nginx(キャッシュ)|
|5.47 |14.74 |335.43 |

キャッシュありは比較するようなものではありませんが、とても早いですね。
キャッシュ効かせなくても通常のapacheよりは軽快に動作してくれそうです。

wordpressのtopsy retweet buttonプラグインのタイトルの文字化け

twitterなんて全然触らないけど、このブログも雰囲気だけはそれっぽくしたいということで、retweetボタンなんてものを設置してますが、どうもretweetを押すと文字化けしてるらしい。
検索して2〜3つみてみると、topsyのスクリプトの引数に渡せ、とか、topsy retweet buttonプラグインだとがんばったけど無理だったとか書いてるので僕もあきらめました。

でも、直接テンプレートに書いてもいいけど、プラグインの方が楽ですよね。導入楽だし、テンプレートを変えても使えるしね。

topsy/topsy.php
[php]
function topsy_generate_retweet_button($size = ‘small’, $css_opts = ”) {
$which_class = ‘data’;
if (! in_array(‘topsy_filter_the_content’, topsy_fn_backtrace())) {
$which_class = ‘shortcode’;
}
$hostname = ‘button’;
$url = urlencode(get_permalink());
if (preg_match("/[?&]topsybeta=1/", $_SERVER[‘REQUEST_URI’], $match)) {
$hostname = ‘beta.button’;
$url .= $match[0];
}
global $post;
$short_url = get_post_meta($post->ID, ‘topsy_short_url’, true);
if ($short_url) $short_url = "", "shorturl": "$short_url";
$title = str_replace(‘"’, ‘"’, $post->post_title);

$hashtags = get_option(‘topsy_auto_hashtags’);
if ($hashtags == ‘post’ && get_the_tags()) {
foreach (get_the_tags() as $tag) {
$title .= ‘ #’ . $tag->name;
}
} elseif ($hashtags != ‘none’ && $hashtags != ‘post’) {
foreach (preg_split("/[, ]+/", $hashtags) as $tag) {
$title .= " #$tag";
}
}
$title = urlencode($title); /* これ追加すると文字化けしないよ */

$ret = str_replace(‘&’, ‘&’, "{ "url": "$url$short_url"") . ", "style": "$size", "title": "$title" }";
$coded = rawurlencode($ret);
if (get_option(‘topsy_use_preloader’) == ‘on’) {
$ret = str_replace(‘"’, ‘\\"’, $ret);
$inner_script = "<script type="text/javascript">topsyWidgetPreload($ret);</script>";
} else {
$inner_script = ”;
}
if ($css_opts) {
$css_opts = trim($css_opts);
if (substr($css_opts, -1) != ‘;’) $css_opts .= ‘;’;
$css_opts .= ‘ ‘;
}
$theme = topsy_simplify(get_option(‘topsy_button_theme’));
return "<div class="topsy_widget_$which_class topsy_theme_$theme" style="${css_opts}background: url(data:,$coded);">$inner_script</div>n";
}
[/php]