• メモ

    ひさびさにApacheのログを見てたらWarningでまくり。

    ImageMagick関連のワーニングでぐぐってみたら同じ症状の人を発見。

    Library not loaded: /opt/local/lib/libMagickWand.4.dylibと出た時は – 鰹出汁の心太

    なるほどlibMagickWandとlibMagickCoreのシンボリックリンクを貼ればいいのね。

    $ cd /opt/local/lib
    $ sudo ln -s libMagickWand.5.dylib libMagickWand.4.dylib
    $ sudo ln -s libMagickCore.5.dylib libMagickCore.4.dylib

    apachectl stopしてstartしたらワーニングでなくなった。

    sigesabaさんありがとう。

    Top


  • teruchiです。

    今日はFacebookのAPIで遊びましょう。

    今回はCakePHPを使ってサクっと作ってしまおうと思います。

    ポイントは、

    ・CakePHPを使う
    ・FacebookのPHP sdkを使う
    ・Facebookアプリの登録、設定

    のあたりでしょうか。

    完成形はこちら
    http://genieframelamp.com/

    (URLは今後変更になると思います)

    「Log In」をクリックして、Facebookでアプリの許可をすると
    リストのページへ飛びます。
    (自動で飛ばない場合は再読み込みしてください)

    検証環境はこんな感じ

    ・Mac OS X Lion (10.7.2)
    ・Apache 2.2.21 (MacPorts)
    ・PHP 5.3.8 (MacPorts)
    (こちらは無くても動くはず)
    ・MySQL 5.1.57 (MacPorts)

    さて、どんどん行きましょう。

    PHPのSDKがFacebookから出てますので、それを使います。

    ドキュメントはこちら
    https://developers.facebook.com/docs/reference/php/

    sdkのダウンロードはこちら
    https://github.com/facebook/php-sdk

    ダウンロードして解凍したフォルダの中にある src フォルダを、
    facebook とリネームして、app/vendors フォルダにコピーします。

    あとはCakePHPでControllerとViewを作成します。

    ControllerはRankingControllerとしておきましょう。

    <?php
    class RankingController extends AppController {
    	var $uses = array();
    	
    	function index() {
    		App::import('Vendor', 'facebook');
    
    		$facebook = new Facebook(array(
    			'appId'  => '261137913930180',
    			'secret' => 'df6442de267eb23f2d8aa0a26a061544',
    		));
    		
    		try {
    			if($facebook->api('/me')) {
    				$this->redirect(array('action' => 'view'));
    			}
    		} catch(FacebookApiException $e) {
    		}
    		
    		$this->set(compact('facebook'));
    	}
    	
    	function view($page=0) {
    		App::import('Vendor', 'facebook');
    
    		$facebook = new Facebook(array(
    			'appId'  => '261137913930180',
    			'secret' => 'df6442de267eb23f2d8aa0a26a061544',
    		));
    
    		if(!($facebook->getUser())) {
    			$this->redirect(array('action' => 'index'));
    		}
    
    		try {
    			$me = $facebook->api('/me');
    			
    			$offset = $page ? $page * 20 : 0;
    			
    			$likes = $facebook->api('/me/likes?limit=20&offset='.$offset.'&fields=id,name,picture,link,likes,category,website');
    		} catch(FacebookApiException $e) {
    			$this->redirect(array('action' => 'index'));
    		}
    		
    		$this->set(compact('page', 'me', 'likes'));
    	}
    }
    ?>
    

    ここでポイントはviewアクションでFacebook::api()を叩いてるところ。

    ドキュメントをみてもなかなか見つからないのですが、
    こことか
    http://developers.facebook.com/docs/reference/php/facebook-api/

    ここ
    http://developers.facebook.com/docs/reference/api/

    のあたりを読み込んで、いろいろ試してみたらこんな使い方が出来ることが判明。

    あとはViewです

    まずindex.ctp

    <div id="fb-root"></div>
    
    <script>
      window.fbAsyncInit = function() {
        FB.init({
          appId      : '<?php echo $facebook->getAppId(); ?>', // App ID
          status     : true, // check login status
          cookie     : true, // enable cookies to allow the server to access the session
          oauth      : true, // enable OAuth 2.0
          xfbml      : true  // parse XFBML
        });
    
    	FB.Event.subscribe('auth.login', function() {
    		window.location.reload();
    	});
      };
    
      (function(d){
         var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
         js = d.createElement('script'); js.id = id; js.async = true;
         js.src = "//connect.facebook.net/en_US/all.js";
         d.getElementsByTagName('head')[0].appendChild(js);
       }(document));
    </script>
    
    <fb:login-button scope="user_likes"></fb:login-button>
    
    

    FacebookのJavascript APIを使って、初期化とログイン後にリロードするように設定しています。

    最後に一覧用のView。view.ctp

    <h2>Facebookでいいね!したリスト</h2>
    
    <h3>me</h3>
    
    <p>名前:<?= $me['name'] ?></p>
    
    <br>
    
    <h3>Likes</h3>
    
    <table>
    <tr>
    <th>category</th>
    <th>name</th>
    <th>image</th>
    <th>Facebook Page</th>
    <th>url</th>
    </tr>
    <? foreach($likes['data'] as $data) : ?>
    <tr>
    <td><?= $data['category'] ?></td>
    <td><?= $data['name'] ?></td>
    <td><img src="<?= $data['picture'] ?>"></td>
    <td><?= $data['link'] ?></td>
    <td><?= @$data['website'] ?></td>
    </tr>
    <? endforeach; ?>
    </table>
    
    <? if($page > 0) : ?>
    <?= $this->Html->link('前の20件', array($page-1)) ?> | 
    <? endif; ?>
    <?= $this->Html->link('次の20件', array($page+1)) ?>
    

    最大件数とかを取ってくる方法が分からなかったので、
    固定で20件づつ表示してます。

    今日はここまで

    Top


  • teruchiです。

    サービス開発中に、メール送信のテストをしたいけど、
    外には送信したくない、もしくは送信できない場合、
    ローカルにメールサーバーを構築しちゃいます。

    DovecotとPostfixが扱いやすいのでこの2つを選びます。

    まずはportsを更新しておきましょう。

    $ sudo port selfupdate
    

    ではDovecotから。

    $ sudo port install dovecot2
    

    ビルド終了時に

    Configuration files go to this directory. See example configuration files in
    /opt/local/share/doc/dovecot/example-config/
    

    って書いてあるので、該当ディレクトリにあるファイルをいくつかコピー

    $ sudo cp /opt/local/share/doc/dovecot/example-config/dovecot.conf /opt/local/etc/dovecot
    $ sudo cp /opt/local/share/doc/dovecot/example-config/conf.d /opt/local/etc/dovecot
    

    conf.dには各種インクルードファイルがおいてあるのでそのままコピーしておくといいです。

    Dovecotを設定しましょう

    $ sudo vi dovecot.conf
    
    protocols = imap
    
    #!include conf.d/*.conf
    !include conf.d/10-master.conf
    !include conf.d/10-auth.conf
    
    #!include_try local.conf
    
    ssl = no
    
    mail_location = maildir:~/Maildir
    

    プロトコルはimapだけでいいと思います。
    10-master.confには基本動作に必要な設定が書かれているのでインクルード。
    10-auth.confではプレーンテキストでのログインとauth-system.conf.extがインクルードされているので必要。
    sslの設定は面倒なので利用不可にしてしまいます。

    重要なのがauth-system.conf.extの設定です。

    passdb {
    driver = pam
    # [session=yes] [setcred=yes] [failure_show_msg=yes] [max_requests=]
    # [cache_key=] []
    #args = dovecot
    args = login
    }
    

    pamの設定ですがデフォルトではdovecot用に設定を用意しなければいけないので、
    「args = login」としてmacの認証(表現は正しくないけど)を利用するようにします。

    では起動しましょう。

    $ sudo port load dovecot2
    

    最近のMacPortsは「port load」でlaunchctlのloadとstartまでやってくれます。

    これでひとまずimap接続が出来るようになりました。

    次にPostfixをいれます。
    標準でPostfixが入っていますが、
    開発環境用にはMacPortsのものを使いたいので新たに入れます。

    $ sudo port install postfix
    

    aliasデータベースが作られてないようなので

    $ cd /opt/local/etc/potfix
    $ sudo newaliases
    

    dovecotに合わせて

    $ sudo vi /opt/local/etc/potfix/main.cf
    
    home_mailbox = Maildir/
    

    さて、ここがポイント。
    このまま起動してもPHPなどから呼び出される/usr/sbin/sendmailコマンドは
    標準でインストールされているPostfixのものが使われてしまいます。
    そうすると、sendmailコマンドを使った時だけMaildir形式じゃない状態になったりと、
    おかしな動きになります。

    置き換えてしまいましょう。

    $ sudo mv /usr/sbin/sendmail /usr/sbin/sendmail.org
    $ sudo ln -s /opt/local/sbin/sendmail /usr/sbin/sendmail
    

    Linuxディストリだと設定ファイルで切替ができるのにMacPortsは/opt配下だけに
    対象を限定するのが基本だからでしょうかね。

    では起動

    $ sudo port load postfix
    

    出来上がり。

    うまく動かないときは/var/log/maillogを見るとわかるかもしれません。

    検証環境
    Mac OS X 10.7.1 (Lion)
    MacPorts 2.0.3
    dovecot 2.0.13
    postfix 2.8.5

    Top


  • Appleが年末に発表されるかもしれない新カテゴリのプロダクツって何だろう?
    teruchiです。

    (以下はMobileMeを使ってて、「どこでも My Mac」が有効になっていることが前提です)

    Mac OS X Lionを使ってて、リモートから接続しようとしたら、
    画面共有ができない(汗
    どうやら「画面共有」が有効になってないっぽい。
    でも大丈夫。(な人はどれほどいるのだろう。。。)

    まずはsshでログイン


    local $ ssh -l (ユーザー名) (ホスト名).(MobileMe ID).members.mac.com

    ログインしたら、launchctlを使ってサービスを有効化。


    remote $ cd /System/Library/LaunchDaemons/
    sudo launchctl load -w com.apple.screensharing.plist

    Finderで共有マシンを見ると「画面を共有…」が有効になってます。

    こちらのサイトに載ってました。
    Snow Leopard (10.6.x)での方法も書いてあります。

    http://ycode.blogspot.com/2011/08/enabling-screen-sharing-on-mac-os-x.html

    ではよい週末を。

    Top