Gmail Java IMAP Extensionを使ってGmailを既読にする

以前、こちらのエントリでGmailをIMAPを使って読み込む手法を紹介しました。

Gmailのメールの本文を直接開くURLを取得する方法

今回は同じGmailのIMAP用ライブラリを使用して、Gmailの特定のメールを既読にする手法を紹介します。

では早速ソースコードです。

package work;

import java.util.Properties;

import com.google.code.com.sun.mail.imap.IMAPSSLStore;
import com.google.code.javax.mail.Folder;
import com.google.code.javax.mail.Message;
import com.google.code.javax.mail.MessagingException;
import com.google.code.javax.mail.Session;
import com.google.code.javax.mail.Flags.Flag;
import com.google.code.javax.mail.search.GmailMessageIDTerm;

public class Sample {

	public static void main(String[] args) throws MessagingException{
		final String email = "email@gmail.com"; //メールアドレス
		final String password = "password"; //パスワード
		final String host = "imap.gmail.com"; //GmailのIMAPホスト名
		final String messageId = "xxxxxxxxxxxxxxx";  //既読にするメールのID(16進数表記)

		Properties props = new Properties();
		props.setProperty("mail.store.protocol", "imaps");
		Session session = Session.getDefaultInstance(props, null);
		IMAPSSLStore store = new IMAPSSLStore(session, null);
		Folder inbox = null;

		try {
			store.connect(host, email, password);
			inbox = store.getFolder("Inbox");
			inbox.open(Folder.READ_WRITE);

			GmailMessageIDTerm term
				= new GmailMessageIDTerm(Long.toString(Long.parseLong(messageId, 16)));
			Message[] messages = inbox.search(term); //対象のメッセージを検索
			if(messages != null){
				for(Message message : messages){
					if(message != null){
						message.setFlag(Flag.SEEN, true); //メッセージを既読にする
					}
				}
			}
		}catch (Exception e) {
			e.printStackTrace();
		}finally{
			if (inbox.isOpen()) {
				inbox.close(true);
			}
			if(store.isConnected()){
				store.close();
			}
		}
	}
}

なお、上記のコードはメッセージIDを使ったGmailの検索の例でもあります。
GmailのメッセージIDは各メールを開いた際のURLの末尾にある16進数になります。

で、実際に検索を行う際はこの16進数表記の文字列をロング値に変換してやる必要があるので注意が必要です。

IE9 iframeを用いたサイトのドキュメントモード

IE9においてiframeを用いたサイトを構築する場合、フレーム内のドキュメントモードに注意する必要があります

iframe Handling (英語)によると、IE9 では、iframe 内のドキュメント モードはトップ レベルの Web ページのドキュメント モードで決まります。トップ レベルの Web ページが IE9 標準モードでない場合、iframe内のサブドキュメントはどのような指定をしても IE9の標準モードではレンダリングできません。

例えば以下の様なコンテンツを作成したとします。

■ index.html

<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'/>

<!-- ドキュメントモードにIE8標準モードを指定 -->
<meta http-equiv="X-UA-Compatible" content="IE=8">

<title>index</title>
<script type="text/javascript">
window.onload = function(){
var mode = document.documentMode;
document.body.innerHTML = "Document mode: " + mode;
};
</script>
</head>

<body>
<iframe id="ifrm" src="contents.html" />
</body>
</html>

■ contents.html

<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'/>

<!-- ドキュメントモードにIE9標準モードを指定 -->
<meta http-equiv="X-UA-Compatible" content="IE=9">
<title>contents</title>
<script type="text/javascript">
window.onload = function(){
var mode = document.documentMode;
document.body.innerHTML = "Document mode: " + mode;
}
</script>
</head>

<body>
</body>
</html>

上記の例ではindex.html内にiframeを配置し、その中にcontents.htmlを表示するような指定となっています。contents.htmlはmetaタグの指定によりIE9標準モードでのレンダリングを行うよう指定していますが、トップレベルであるindex.htmlはmetaタグの指定によりIE8標準モードでのレンダリングとなっています。このような状態でindex.htmlをIE9で表示すると、contetns.htmlはmetaタグの指定に関わらず、IE8標準モードでレンダリングされることになります。

このようにiframe内のコンテンツがコンテンツ制作者の意図しないドキュメントモードでレンダリングされないようにするため、サイト内にiframeを用いる場合はトップレベルのドキュメントモードをIE9標準モードとする必要があります。

jQuery MobileでマークアップHTMLを動的に作成するときに使うメソッドまとめ

普通jQuery Mobileを利用するときは、枠はhtmlで書きます。
例:JQueryのlistviewの使い方

<ul data-role="listview">
 <li><a href="acura.html">Acura</a></li>
 <li><a href="audi.html">Audi</a></li>
 <li><a href="bmw.html">BMW</a></li>
</ul>


なかなか必要に迫られないかもしれないけど、上記のコードをjavascriptで動的に作成したいときは以下のようにします。

$('<ul/>')
 .attr("data-role","listview")
 .append($('<li><a href="acura.html">Acura</a><li/>')
 .append($('<li><a href="audi.html">Audi</a><li/>')
 .append($('<li><a href="bmw.html">BMW</a><li/>');


でもこれだけだと、CSSのスタイルが適用されません。
上記に加えてlistview()メソッドを呼ぶとスタイルが適用されます。

$('<ul/>')
 .attr("data-role","listview")
 .append($('<li><a href="acura.html">Acura</a><li/>')
 .append($('<li><a href="audi.html">Audi</a><li/>')
 .append($('<li><a href="bmw.html">BMW</a><li/>');
 .listview('refresh'); // <- ここ!

jquery mobileには上記のようなメソッドがいくつかあります。
結構公式ページでもその辺が全て一箇所でまとまってないので、まとめておきます。

あらゆる要素に対して

$('</div>').appendTo( ".ui-page" ).trigger( "create" ); // div 以外に対しても可

navbarに対して

公式ドキュメント内には使い方が載ってないのですが、できてしまいます。非公式なのかな。。

$('<div data-role="navbar"/>')
	.append($('<ul/>')
		.append($('<li><a href="a.html">One</a></li>'))
		.append($('<li><a href="b.html">Two</a></li>'))
	).navbar(); // <- ここ!

select に対して

$("#selectfoo").selectmenu("refresh") ;

チェックボックスに対して

$("input[type='checkbox']").checkboxradio("refresh");

ラジオボタンに対して

$("input[type='radio']").checkboxradio("refresh");

スライダーに対して

$("input[type='range']").slider("refresh");

参考

http://jquerymobile.com/demos/1.2.0/docs/forms/docs-forms.html

GrailsでOpenIDのチュートリアル

最近はコード書くよりRedmineとにらめっこしています。
こんにちわ、DiceK Mikamiです。

Grailsの2.2.0がリリースされましたね。
今回は2.2.0を使って、OpenID実装のチュートリアルを実践してみたいと思います。
 
 

検証環境

  • Java: JDK1.7.0
  • Grails: 2.2.02.2.0 RC2

 

プラグインのインストール

OpenID環境の実装には、Spring Security OpenIDプラグインを利用します。
このプラグインはSpring Security Coreを中核としたOpenID用プラグインです。
さて、ここで一つ大問題があります。
なんと現在(2013/02/07)、Spring Security CoreがV2.2.0で動きません。
ちゃんとチュートリアル通りに動かしても以下のようなエラーが返ってきます。

grailsopenid02
なんでしょうか。
私の環境が悪いのでしょうか。
それとも日々の行いが悪いからでしょうか。
へこみます。
一体私が何をしたというのだ!

気を取り直して、ここでは2.2.0 RC2を使うことにします。(なぜかRC版では動くのです)
さっそくコマンドプロンプトからアプリ作成します。

$ grails create-app openidsample
$ cd openidsample

次に、プラグインをインストールしていきましょう。
と、いきたいところですが、しばしお待ちください。
チュートリアルでは、サクッとプラグインをインストールしていますが、この通りにやっても動きません。
ここはチュートリアルに掲載されていない重要な作業です!
プラグインの中では、Google Guice2.0を利用しているのですが、セントラルリポジトリにありません。
インストールページには、BootConfig.groovyにリポジトリを追加しろと記載されていますが、残念なことにこんなことでは動かないのです。
理由は不明ですが、どうやらリポジトリのURLが2.0のものではないようです。
仕方ないので、自前でGoogle Guice2.0を用意しましょう。
guice-2.0.jarというファイルが必要になりますので、「 guice-2.0.jar download 」とかで検索すればダウンロードサイトがヒットすると思います。
そこからダウンロードしてください。
ダウンロードしたguice-2.0.jarを以下の画像にあるフォルダに入れておきます。

grailsopenid01

このフォルダに入れておくとローカルライブラリとしてGrailsが勝手に処理してくれます。
ここまでの作業が終わりましたら、プラグインをインストールします。

$ grails install-plugin spring-security-openid

spring-security-openidはspring-security-coreに依存しているんで、勝手にそちらもインストールしてくれます。
余談ですが、私の環境ではインストールしてくれませんでした。ので、別途spring-security-coreをインストールしました。嫌われているのでしょうか。
 
 

雛形の作成

Grailsは最近の流行りよろしくほとんどがコマンドで作成できます。
もう障害はないので、雛形をバリバリ作っていきます。

$ grails s2-quickstart com.openidsample User Role
$ grails s2-init-openid
$ grails s2-create-persistent-token com.openidsample.PersistentLogin
$ grails s2-create-openid com.openidsample.OpenID

ここで作成されるファイル群は、サーバ側のアカウント管理、OpenIDとの紐付け、トークン管理を行うクラスです。
 
 

雛形の改良

単純にコマンドだけでは、OpenIDとの紐付けは行ってくれませんので、OpenID用にカスタマイズする必要があります。

grails-app/domain/com/openidsample/User.groovy

package com.openidtest

class User {
	String username
	String password
	boolean enabled
	boolean accountExpired
	boolean accountLocked
	boolean passwordExpired

	// hasManyを追加する
	static hasMany = [openIds: OpenID]

	static constraints = {
		username blank: false, unique: true
		password blank: false
	}

	static mapping = {
		password column: '`password`'
	}

	ー後略ー
}

次に、BootStrap.configでロールなどを追加しておきます。

grails-app/conf/BootStrap.groovy

import com.openidsample.Role
import com.openidsample.User
import com.openidsample.UserRole

class BootStrap {
	def springSecurityService

	def init = { servletContext ->
		String password = 'password'

		def roleAdmin = new Role(authority: 'ROLE_ADMIN').save()
		def roleUser = new Role(authority: 'ROLE_USER').save()

		def user = new User(username: 'user', password: password, enabled: true).save()
		def admin = new User(username: 'admin', password: password, enabled: true).save()

		UserRole.create user, roleUser
		UserRole.create admin, roleUser
		UserRole.create admin, roleAdmin, true
	}
}

一緒にユーザーも作っています。
これはローカルサーバーのユーザーです。
次にURLマッピングも若干変更します。
これはSpring Security Coreが作成したログイン画面ではなく、OpenID用のログイン画面に遷移させるために行います。

grails-app/conf/UrlMappings.groovy

class UrlMappings {
	static mappings = {
		"/login/auth" { 
			controller = 'openId'
			action = 'auth' 
		}

		"/login/openIdCreateAccount" {
			controller = 'openId'
			action = 'createAccount'
		}

	ー後略ー
	}
}

 

テスト用ファイルの作成

次にテスト用にセキュアなページを作っておきます。

$ grails create-controller secure

内容は簡単にロールによって表示ページを分けるようにします。

grails-app/controllers/openidsample/SecureController.groovy

package openidsample

import grails.plugins.springsecurity.Secured

class SecureController {
	// 管理ユーザー用
	@Secured(['ROLE_ADMIN'])
	def admins = {
		render 'Logged in with ROLE_ADMIN'
	}

	// 一般ユーザー用
	@Secured(['ROLE_USER'])
	def users = {
		render 'Logged in with ROLE_USER'
	}
}

 

実験

ここまで作成しましたら、あとは実験してみます。

$ grails run-app

起動しましたら、 http://localhost:8080/openidsample/secure/users にブラウザからアクセスしてみましょう。

grailsopenid03

ログインできていないので、上画面のようなログインページが表示されると思います。
今回はGoogleを利用しようと思いますので、テキストボックスにGoogleのOpenID用URLを入れてログインしましょう。

Google OpenID用URLhttps://www.google.com/accounts/o8/id

指示の通り操作を行うと、ローカルサーバーのトップ画面に戻ってきます.
途中でアカウントを作るように促されますが、これはローカルサーバーのアカウントとの紐付けを行うためのものです。
再度 http://localhost:8080/openidsample/secure/users にブラウザからアクセスします。
以下のような画面が表示されれば成功です。

grailsopenid04
ひとまずチュートリアルとしてはこのような感じとなります。
認証サーバーのURLは固定ですのでそれをボタンにしたり、紐づけたアカウントに管理権限をつけたりと言った改造を施せば簡単にOpenID連携をしたアプリを構築できると思います。
プラグインがもう少し安定すれば実践でも使っていけるでしょう。
 
 

参考URL

http://grails-plugins.github.com/grails-spring-security-openid/

EC2上のTomcatからRDSにSSL接続する方法

今回はAWSのEC2にインストールしたTomcatから、RDS(MySQL)にSSLで接続する方法を紹介します。

準備

  • EC2インスタンス(Linux) *1
  • RDSインスタンス *1
  • EC2インスタンスにTomcatをインストールしておく
  • RDSインスタンスのセキュリティグループで、EC2インスタンスからのアクセスを許可しておく

以下のサイトを参考にして設定を行ったところ、SSL接続に成功しました。

Amazon RDS に SSL 接続する (JDBC編)
http://blog.cles.jp/item/5349


以下手順です。

まずはMySQLのクライアントからRDSに接続します。
以下のコマンドを実行して、任意のユーザからはSSL接続のみ許可します。

# mysql -u root -p -h ***.***.ap-northeast-1.rds.amazonaws.com
mysql> GRANT ALL PRIVILEGES ON dbuser.* TO dbuser@"%" IDENTIFIED BY 'mysqlpassword' REQUIRE SSL;


次にAmazonから証明書を取得します。
Amazonから配布される証明書はPEM形式であるため、JKS形式に変換する必要があるようです。

# wget https://rds.amazonaws.com/doc/mysql-ssl-ca-cert.pem
# /usr/java/default/bin/keytool -keystore amazon.jks -importcert -file mysql-ssl-ca-cert.pem
パスワードを2回入力(ここでは jkspassword とします)
・
・
・
Trust this certificate? [no]:  yes(yesと入力してEnter)
Certificate was added to keystore
#


作成したJKSファイルを任意のフォルダに移動します。

# mkdir /opt/jks
# mv amazon.jks /opt/jks


最後にTomcatのサーバーのserver.xmlまたはコンテキストファイルでDBとの接続設定をします。

<Resource name="jdbc/testDB" auth="Container"
           type="javax.sql.DataSource"
           username="dbuser"
           password="mysqlpassword"
           driverClassName="com.mysql.jdbc.Driver"
           url="jdbc:mysql://***.***.ap-northeast-1.rds.amazonaws.com:3306/dbName?useUnicode=true&characterEncoding=UTF-8&useSSL=true&requireSSL=true&verifyServerCertificate=true&trustCertificateKeyStoreUrl=file:///opt/jks/amazon.jks&trustCertificateKeyStoreType=JKS&trustCertificateKeyStorePassword=jkspassword"
/>


SSLに関係しているURLのパラメータは以下です。

useSSL=true
requireSSL=true
verifyServerCertificate=true
trustCertificateKeyStoreUrl=file:///opt/jks/amazon.jks  #作成したJKSファイルのパス
trustCertificateKeyStoreType=JKS  #JKS形式を指定
trustCertificateKeyStorePassword=jkspassword  #JKS作成時に設定したパスワード

infoScoopをeXcaleにインストールしてみる

新年あけましておめでとうございます。
性懲りもなく帰ってきました。
本日は表題の通り軽めの内容でお送りしたいと思います。
 
 

eXcaleとは

eXcaleとは、TIS株式会社によってアプリケーション開発者向けPaaSとして提供予定のクラウドサービスです。
現在のところRuby、Java、PHP、Node.jsのアプリケーションを動作可能なプラットフォームとなっています。
2013年4月に正式公開ですので、現在のところベータ運用されています。
ベータ期間中はサインアップすれば無料で使えますので、折角ですのでinfoScoopをインストールしてみたいと思います。
 
 

準備するもの

  • infoScoop OSS クイックスタート

 

セットアップ

1.eXcaleにアプリケーションを作成

まずは、eXcaleに入れ物となるアプリケーションを作成します。

ここで作成したアプリケーション名は、後々JNDI名(とアクセスURL)になりますので、慎重につけましょう。
 

2.infoscoop-3.1.0-quickstartの取得

まずは、「infoscoop-3.1.0-quickstart」をダウンロードしてきます。
ダウンロードしたファイルを展開し、以下のファイルを取得しておきます。

  • init_infoscoop.ja.sql
  • apache-tomcat-6.0.28/webapps/infoscoop.war

sqlファイルは初期データを投入するのに使います。
クイックスタートを使うのは、このファイルがあるためです。
 

3.datasource.xmlを修正

現状ではJNDI名がeXcaleで作成されたアプリケーション名と同じになってしまうので、変更します。
通常版のremakewarを利用すればJNDI名を変更できますが、動かなかったので一部修正を含めて、泥臭い方法で修正します。

取得したwarファイルの拡張子をzipに変更し、適当な場所に展開します。(一般的なファイル展開ツールで展開することができます)
展開したファイルに含まれているdatasource.xmlを修正します。

/WEB-INF/classes/datasource.xml

〜修正前〜
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
	<property name="jndiName">
		<value>java:comp/env/jdbc/infoscoop</value>
	</property>
</bean>

〜修正後〜
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
      <property name="jndiName" value="jdbc/<eXcaleに作成するアプリケーション名>" />
      <property name="resourceRef" value="true" />
</bean>

4.web.xmlの修正

次に、web.xmlも修正します。

/WEB-INF/web.xml

〜修正前〜
<resource-ref>
    <res-ref-name><!--start dataSource.jndiName-->
		jdbc/infoscoop
	<!--end dataSource.jndiName--></res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

〜修正後〜
<resource-ref>
    <res-ref-name><!--start dataSource.jndiName-->
		jdbc/<eXcaleに作成するアプリケーション名>
	<!--end dataSource.jndiName--></res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

5.infoscoop.warの作成

変更が終わりましたら、展開したフォルダを丸ごとzip圧縮します。
その後、拡張子をwarに変更して、warファイルの慣性です。
 

6.作成したアプリケーションに初期データを投入

 さて、早速デプロイといきたいところですが、アップロードすると自動的にデプロイまで行ってしまいますので、先に初期データを投入します。


 

7.warファイルのデプロイ

最後に、warファイルをアップロードして完了です。

5〜10分ほどでアクセスできるようになるかと思います。
 
 

参考URL

TIS株式会社
eXcale
infoScoop OpenSource

GrailsからSolrを呼び出すサンプル

今年も残すところあと6時間ほどになりました。
今年一年を振り返ると、苦しいこと、辛いこと、、、あれ、目から熱い水がこぼれてくるぞ。
どうもこんにちわ、DiceK Mikamiです。

さて、今年最後のテーマは“Grailsを使って、Apache Solrで検索したデータを取得する”です。
 
 

Apache Solrとは

Apache Solrは、Apache Luceneをコアに持つJavaで書かれたオープンソースの検索エンジンです。国内外の大規模検索サービスで利用実績を持ちます。
国内で言えばAmebaや価格.comなどで使われているそうです。
Solrの特徴として、ファセット検索が挙げられます。
ファセット検索(ファセットナビゲーション、ファセット分析とも)とは、様々なカテゴリー(例えば、分類や期間)を前もって用意しておき、それをユーザーが選択することで検索を行うと言うものです。
また、その検索条件もヒット数などに基づいて提供されるので、“ハズレ”がありません。
「検索したはいいけど1件もヒットしなかった」などということは、このファセット検索においてはありえないのです。
Solrはこのファセット検索のインターフェースを持っています。
 

環境

  • Grails: 2.2.0-RC1
  • Java: 1.7.0_10-ea
  • Apache Solr: 4.0.0
  • solr-solrj: 4.0.0-BETA

 

サンプル

さて、RESTインターフェースを持っているのであれば、AjaxリクエストなりHTTP Clientなりで接続すれば良い訳ですが、それではあまりにも面白くない。
ということで、今回はSolrが持っているJavaクライアントsolrjを利用してみようと思います。
イメージは下図のような感じです。


 

Mavenリポジトリから取得する設定

Grailsには膨大な数のプラグインが存在します。
もちろんその中にもsolrjはあるのですが、なんとも残念なことに古いものしかありません。
ですので、BuildConfig.groovyに少し細工をしましょう。

/grails-app/conf/BuildConfig.groovy

dependencies {
    compile 'org.apache.solr:solr-solrj:4.0.0-BETA'
}

これで起動時にsolrjをMavenリポジトリからダウンロードしてくれます。
(サンプルでは4.0.0-BETAとなっていますが、適宜gradleの記法にあわせて書き換えて下さい)
 

実際に利用する

今回はコントローラーに実際のコードを入れてみます。

class SolrController {
    def index() {
        def url = 'http://localhost:8389/solr/collection1'
            
        // サーバーを作成
        SolrServer server = new HttpSolrServer(url)

        // パラメータを設定
        SolrQuery query = new SolrQuery()
        query.setParam('q','*:*')
        query.setParam('facet','true')
        query.setParam('facet.field','compName_s')
        
        //リクエスト
        QueryResponse resp = server.query(query)

        //レスポンスの処理
        ['queryResults': resp.getResults(), 'facetField': resp.getFacetFields()]
    }
}

たったこれだけでSolrから検索結果を取得できます。
また、このサンプルではHttpリクエストを利用していますが、EmbeddedSolrServerクラス(ローカルにSolrがある場合に高速にアクセスする)やLBHttpSolrServerクラス(ロードバランスを考慮して、呼び出しSolrを選択する)といった複数の呼び出し形態がありますので、Solrがどのような構成で存在するかによって適切なクラスを利用できると言うのも魅力的です。
今回はGrailsでの利用方法をサンプルとして紹介しましたが、ライブラリ自体はJavaですので、Javaアプリケーションにもすぐに取り込めるかと思います。
参考までにGitHubにサンプルコードを公開いたします。
 
 
最後になりましたが、今年一年、私の駄文にお付き合いいただきありがとうございました。
懲りずに来年も書ければいいなぁなどと寒空を眺めております。
ともあれ、皆様よいお年をお迎え下さい!!
 

参考URL

Apache Solr
Maven Repository – solrj
Solrjサンプルコード集
サンプルコード(GitHub)

Google乗換案内をちょっと便利にするRoute Searchガジェットの使い方

目的地に移動するときに、どんなサービスやアプリを使って経路や乗換を調べていますか?
今回はGoogle乗換案内をちょっと便利にするガジェットを紹介します。

route_search1

Goolge乗換案内

Google乗換案内
http://www.google.co.jp/intl/ja/landing/transit/

Google乗換案内は、Googleマップに組み込まれています。
https://www.google.co.jp/maps?f=d

乗換案内というと出発・到着の駅名を入力するというイメージがあるかもしれませんが、
Google乗換案内では、出発地・到着地に駅名の他に、住所や地名、建物を入力して経路検索ができます。

例えば、
 出発:新宿区西新宿1-24-1
 到着:品川駅

 出発:東京タワー
 到着:スカイツリー
のような検索ができます。

Route Searchガジェット

Route Searchガジェットは、ガジェット上で出発地・目的地・時刻を入力して検索ボタンをクリックすると、別タブでGoogleマップの画面が表示されるシンプルなガジェットです。
route_search8

また、Google乗換案内を便利にする以下の2つの機能があります。

1. 検索履歴
 1つ目は検索履歴です。
 経路検索を使うときに毎回出発地と目的地を入力していませんか?
 ガジェットから検索すると、出発地と目的地が履歴に保存されます。
route_search2
 次回から、入力フォームにフォーカスすると過去に検索したキーワード(駅名、地名、住所など)がプルダウンで表示されます。キーボードからの入力なしで検索できます。
route_search3

2. ラベル
 2つ目はラベルです。 検索履歴に任意のラベルをつけることができます。
 履歴を使って過去に検索した住所で検索しようとした場合、プルダウンに住所が表示されてもどこの住所なのかすぐにわかりません。
 ここで、この住所にラベルをつけておきます。
route_search4
 右側の入力フォームをクリックすると、ラベル一覧が表示されます。
route_search5
 ラベルをクリックすると出発地・到着地のキーワードが自動で入力されます。
route_search6
 よく行く場所はラベルをつけておくと、入力がとても楽になります。
 

業務での利用シーン

下記の手順で便利にGoogle乗換案内を使うことができます。
1. お客さんの会社の住所で検索する
2. 1の履歴に会社名などのわかりやすいラベルをつける
3. 1と2をよく行く会社・場所の分だけ繰り返す
4. 自分の会社の住所で検索して、履歴にラベルをつける

入力例
 出発:本社(ラベルから)
 到着:ABC社(ラベルから)
route_search7

どこで使える?

infoScoop上で利用可能です。
infoScoop for Google Appsを利用中であれば、管理画面から簡単にガジェットを追加できます。
infoScoop Cloud EnterpriseやinfoScoop OpenSourceで利用する場合はお問い合わせください。

このガジェット以外にも便利なガジェットがinfoScoop Gadget Galleryに掲載されています。
ぜひお試しください。

infoScoop Gadget Gallery
http://www.infoscoop.info/gadget-gallery/

vert.xでWebSocketする

ある昼下がり、私は ラオウ PMからこうお達しを受けたのです。

「お前のような輩は、WebSocketを使った通知サーバーをつくればいい」

このブログは、そんな指令を受けたプログラマー4時間分の記録である。
こんにちわ、DiceK Mikamiです。
 
 

今回の目的

今回は、WebSocketを通知に利用できないかと言うところが出発点になります。
WebSocketと言えばnode.jsですが、今回はそれ以外のやり方を模索したいと思います。
具体的に実現したいことは以下のような図になります。

勘の良い方はお気づきと思いますが、Pusherと同じです。
ただし、Pusherのようなクラウドサービスにも依存したくありませんし、node.jsはまだ利用したくないという命題がありますので、第3の道としてvert.xを利用します。
 

vert.xとは

vert.xとは、「JVM上で動作する次世代の非同期でスケーラブルな並列処理アプリケーションのためのフレームワーク」だそうです。
平たく言うと、「JVM上で動作するnode.js」だと思っていただいて問題ないかと思います。
また、JVM上で動作するとありますが、開発者は複数の言語を利用することができます。
例えば、RubyやPythonなどと言った流行りの言語でも利用できます。
vert.xではSocketJSをサポートしており、これを使うことでWebSocketの利用を実現できます。
 

実装環境

  • vert.x: 1.3.0-final
  • Java: JDK1.7.0
  • Groovy: 2.0.5
  •  

groovy実装を使う

vert.xに含まれているサンプル「 eventbusburidge 」を改良して、実現したいと思います。
groovyで実装した内容は以下のようになります。

import org.vertx.groovy.core.http.RouteMatcher

def server = vertx.createHttpServer()
def route = new RouteMatcher()

route.get('/') { req -&gt;
	req.response.sendFile('notificationserver/index.html')
}

route.get('/vertxbus.js') { req -&gt;
	req.response.sendFile('notificationserver/vertxbus.js')
}

route.post('/deliver') { req -&gt;
	//Postで通知内容が送られてくることを想定
	req.bodyHandler { body -&gt;
		String channel;
		String message;
		def params = body.toString();
		for(param in params.split('&amp;')){
			def keyval = param.split('=');
			switch(keyval[0]) {
				case 'channel':
					//チャンネルを取得
					channel = keyval[1]	
					break
				case 'message':
					//メッセージを取得
					message = keyval[1]
					break
			}
		}

		//受け取ったら指定チャンネルに通知する
		vertx.eventBus.send(channel, [&quot;message&quot;: &quot;${message}&quot;]);
	}

	req.response.end();
}

def requestServer = server.requestHandler(route.asClosure())
def sockServer = vertx.createSockJSServer(server)
sockServer.bridge([prefix: '/notif'], [[:]], [[:]])
requestServer.listen(8080)

「 /deliver 」にPOST送信された内容を指定したチャネルに流し込むような形です。
通知を受け取るためには、受け手は前もってそのチャネルをサブスクライブしておく必要があります。
基本的な概念は非常にOpenAjaxHubに似ていると思います。
 
これ以外に通知が届かなかった場合の処理をどうするかや堅牢性を担保するための仕組みなどを組み込む必要がありますが、基本的には目的通りの動きになりました。
 

参考URL

vert.x
SockJS
Pusher
infoScoopガジェットとOpenAjax Hub
 
我がコードに一片の悔いなし!!<もういいよ
注意:この記事の枕部分は脚色されています。

rbenv で JRuby をインストール

Rubyのようなバージョン間に互換性があまりない言語を利用するとなると簡単にバージョンを切り替えられる環境が欲しくなります。
RubyではRVMというバージョン切り替えシステムが導入できますが、最近の流行りはどうやらrbenvというもののようです。

rbenvとは
37signalsのsstephensonさんが作成したバージョン管理ツールです。
RVMよりも軽量で、gemの管理とかは一切してくれません。
が、それがいいという方々に大人気?のツールです。

 
今回は、このrbenvを利用して、JRubyをインストールしてみます。
ついでに、gemの管理を行ってくれるrbenv-gemsetもインストールしてみます。
 
 

検証環境

OS: Mac OSX Mountain Lion
 
 

rbenvのインストール

今回もHomebrewを使って、インストールします。
もちろんHomebrewではなくても、yumとかMac Portsとかでも(多少のコマンドは違えど)インストールできます。
でも、Windowsだけは勘弁な。

$ brew install rbenv
$ brew install rbenv-build

はい、サクッと余計なものもインストールしました。
rbenv-buildです。
これはrbenvを通してrubyをインストールする時に、ビルド→インストールを行ってくれるものです。
これが入っていないとビルド→インストールをしてくれません。(自前でコマンドを叩くことになります)
何も考えず、書かれるがままにインストールしましょう。
次に、~/.bash_profileに以下を記述します。

eval &quot;$(rbenv init -)&quot;

最後に、以下をパスに追加しましょう。

$HOME/.rbenv/shims

これでrbenvがインストールされました。
実際にインストールできたかはあとで行います。
 
 

gccのインストール

Mac Lion以降の場合、この処理が必要になります。
この処理を行っていないと、どうやらRubyをビルドする際にエラーになるそうです。
XCodeがインストールされており、かつCommand Line Toolsがインストールされている場合は、全く気にする必要はないのですが、Lion以降ではgccの種類が違うためエラーが起きるようです。
Lionであれば、以下よりGCCのインストーラーを入手できます。

https://github.com/kennethreitz/osx-gcc-installer

Mountain Lionの場合は、素直にXCodeからインストールした方が幸せになれるかと思います。
 
 

JRubyのインストール

rbenv経由でJRubyをインストールしてみましょう。
rbenvでインストールできるものの一覧は以下のコマンドで取得できます。

$ rbenv install -l

「jruby-<バージョン番号>」が一覧に表示されたかと思います。

$ rbenv install jruby-<バージョン番号>
$ rbenv rehash

これでインストール完了です。
rehashコマンドによってrbenvの設定ファイルをリロードしています。
面倒なことにこれはgemのインストールなどを行った時にも行わないといけません。
rbenvコマンドを利用したら、rehashすると覚えておく必要があります。
(rehashを自動的に行うためのスクリプトもありますが、ここでは割愛します)
以下のコマンドで、実際にインストールできたかを確認できます。

$ rbenv versions

インストールしたRubyの一覧が取得できます。
利用状態にあるものの先頭にはアスタリスクが表記されます。
次に、インストールしたRubyを利用状態にします。

// グローバルで利用する
$ rbenv global <利用したいRuby>

 // 特定ディレクトリで利用する
$ rbenv local <利用したいRuby>

// システムインストールのRubyに戻す
$ rbenv global system

 

rbenv-gemsetのインストール

rbenvでgemsetを管理したい人向けのツールです。
rbenvではインストールしたRubyごとにgemを管理しますが、それよりも細かい管理を行ってはくれません。
ですので、それをカバーするためにrbenv-gemsetを導入します。

// インストール
$ brew install rbenv-gemset

// インストールの確認
$ rbenv gemset

バージョン情報が表示されれば、インストールできました。
では、適当にgemsetを用意してみます。

// サンプルのためにディレクトリを作成
$ mkdir sample
$ cd sample

// rgemsetと言う名前で、gemsetを作成
$ rbenv gemset create <利用するRuby> rgemset

// sampleディレクトリでは、rgemsetを利用するように指定
$ echo rgemset &gt; .rbenv-gemset

// アクティブになっているかを確認
$ rbenv gemset active

// 削除したい場合
$ rbenv gemset delete <利用するRuby> rgemset

 

Railsをインストール

折角なので、JRuby on Railsの環境を用意してみます。

// Railsのインストール
$ rbenv exec jgem install rails
$ rbenv rehash

// インストールの確認
$ rbenv exec jgem list

JRubyなのでjgemを使ってみました。
「rbenv exec」コマンドを接頭辞として使うことでrbenv経由になります。
あとは、普通に使ってOKです。

$ jruby -S rails new hoge -m http://jruby.org/rails3.rb

これで雛形は完成です。

フォロー

新しい投稿をメールで受信しましょう。