2015年12月14日月曜日

子持ちエンジニアと仕事

このエントリーは子育てプログラマ・ITエンジニア・Webデザイナー Part 2 Advent Calendar 2015の15日目として書いています。

まずは自己紹介

4歳の娘と2歳の息子の父親です。仕事は、昨年の9月に子育てメディアをやっている会社に転職し、開発全般、ほぼ何でもやっている感じです。
仕事に家庭に、子育てに奮闘する日々を過ごしております。

仕事と家庭と時間

「時間の使い方が子供中心になる」、「自分の自由な時間が少なくなる」とよく聞きますが、実際に本当にその通りだなと思う毎日です。というか、むしろ子供や家族と過ごす時間がたくさん欲しくなります。
そりゃ、「パパといっしょにお風呂入ると楽しい」って言われたら毎日早く帰って風呂入りますよ。「お休みの日は一緒に遊ぼうね」って言われたら土日は子供と遊ぶのが最優先ですよ。だって我が子は可愛いもん(笑)
ただ、そうなると、5:00PMとかに何故かプログラムの神様が乗り移って「ひょー」とか言いながらプログラム書き続けて気がつけば終電、というような働き方はできない訳です(ただし、神様が乗り移っても、生み出すコードが神にはならない不思議)。

エンジニアと仕事

私は、エンジニアという仕事は、成果や事業への貢献度で評価してもらいやすい職種なのかな、と思っています。長い時間会社にいることが直接の価値につながらないというか。
例えば、毎日終電帰りして出した成果と、定時上がりして出した成果が同じだったら、会社に対しての私の価値って同じなんですよね。きっと。
これって、考えようによっては、子持ちのエンジニアにとってすごくいい事なんじゃないかなと。だって、ちゃんと結果が出せていれば、定時に帰って子供と風呂入ったり、家族揃って夕食を食べていいんですもんね。
もちろん一方で、「ちゃんと結果が出せている」ことが大前提になる訳で、プレッシャーもあります。
私自身も、なるべく定時に帰ることを心掛けているのですが、それを理由にスケジュールを甘くしたり(いまは自社サービスの開発をしているので、スケジュールなどは社内で決めている)、クオリティを犠牲にするようなことがないように気をつけています。
子供の有無の関係ない、ごくごく当たり前のことなのですが(笑)、仕事に使える時間を限定する分、より厳しく自分を律しないといけないな、と思っています。家族を言い訳にしちゃいかん!

大事なこと

何より大事なことは、職場の理解です。だって、残業している人を頑張ってるって評価する会社だったら、いくら個人で心がけていても報われないですもんね。
私個人としては、いまの会社は上記のような働き方にも理解があり、子供の急な発熱で出社できない場合でも、自宅作業を認めてくれたり、働きやすくて感謝しています。

さいごに

何だかとりとめもない感じになってしまいましたが、日々思っていることを書いてみました。
明日はtakopom55さんです。

2014年4月27日日曜日

引っ越しすることに

5月いっぱいで今住んでいるところから埼玉県に引っ越すことになりました。昨日に賃貸契約してきました。

実は

今年に入ってから、中古物件購入+リノベーションという最近流行りのカタチで新居を探していました。なぜこのタイミングかといいますと、

  • 来年の4月は、ちょうど長女が年少さんで、保育園 or 幼稚園を探し始める時期だった
  • 今住んでいるところは都区内ということもあり待機児童問題が深刻で、現在専業主婦家庭である我が家がいい条件で保育園や幼稚園を探せる可能性が低い

という感じでした。ということで、より郊外の、折角なので妻の実家に近めの場所で、長く住める理想の住まいを探そう、ということになったのでした。

でも

結局、中古物件の購入ではなく賃貸契約となりました。色々話しあったり、色々あったのですが結果的にこれが我が家にとってベターな選択だったかなと思っています。

  • 私の仕事は、数年後どうなっているかまるで読めない業界なので、私的に将来の見通しが立てづらかった
  • 貯金がそれほど無く、初期費用などを考えれば頭金はゼロでの住宅ローンとなり、正直余裕のない状態だった
  • 秋田の実家を建てなおした時に、父親との共同名義で既に住宅ローンを組んでいたので、二重ローン状態になるところだった

それでも、保育園探しの問題を解決できて、もっと便利でキレイな住まいを、と思って中古物件を探してましたが、なんと賃貸でいい物件が見つかったので、もろもろの不安を抱えて住宅ローンを組むよりいいよね、ということになりましたとさ。

ということで

今年のGWは引越し準備となりそうです。ちなみに通勤時間は30分伸びます。その代わり住環境はかなり良くなりそうなので、色々大変なこともありそうですが、今はただただ楽しみですw

2014年3月23日日曜日

いなかソン

3月21日、22日と、秋田県五城目町にて開催されたいなかソンに参加させて頂いたので、どんな感じだったのか後々の自分自身のためにも、まとめておこうかと思います!

一日目

朝の6時くらいに自宅を出発し、7時36分東京駅発のこまちに乗って単身秋田に向かいます。3連休の初日とあって東京駅は朝から大混雑しておりびっくり。自分の乗った新幹線もほぼ満席といったところ。
4時間後に秋田駅に無事到着。寄り道せずに乗り換えて八郎潟駅へ。秋田出身だけど八郎潟駅は初上陸でした。
送迎で来ていた車にちゃっかり便乗させて頂き、五城目町地域活性化支援センターに到着。最近建てなおしたものの、廃校となってしまった小学校ということで、とにかくきれい!そして木のいい匂いが。


ほどなくしてプログラムが開始。まずは五城目町を知ろう、ということで町内散策へ。となり町出身の自分は何度か来たことがあったものの、知らないこと、新たな発見がたくさんありました。役場職員の方の解説付きで、これがとても楽しかった!


その後は大潟村で農業を営む方のお話をきき、ここまでのインプットを元にアイデアソン!自分は職業病というか、すぐ実現可能性を考えてしまって頭がカチンコチンになってしまうんだけど、頭をやわらかーくしてアイデアが出やすくなるような手法が取られてました。ははーなるほど!と思わず唸ってしまうアイデアもいくつか出ていました。
そして、19時からは一日目のクライマックス(笑)、地元名物だまこ鍋と、地元産の日本酒での交流会!いやー美味でした。


この後はいよいよハッカソン!というところでしたが、会場はお泊りNGということでここで一旦解散。実家に帰った自分は、日本酒でいい感じなっていたこともあり寝てしまいましたとさ(笑)

二日目

二日目は、エンジニアはなんと職員室をお借りしてのハッカソン。エンジニアが集まるとすっかり「いつもの雰囲気」で、もくもくと開発できるいい環境でした。
そして成果発表会!自分が作ったのは「観光案内人(お年寄り)のマッチングサービス」。なんだか業務アプリのようなものを作ってしまって少々反省。ですが、新たなアイデアの呼び水にはなったかな?ということでひとまずOKでしょうか(笑)
他の方の開発したものも、短時間ながらも中々の出来!ブラッシュアップしていけば面白いものが出来そうなものもありました。

ということで

二日間に渡り参加させて頂いたいなかソンですが、終わってみればとても濃密な時間を過ごせました。すごい3連休でした。ということで感想など。

自分は出不精エンジニアなのでハッカソンに参加するのもはじめてでした。なので比較などはできないのですが、「いなかの問題をITで解決する」というテーマがあるのがすごくいいなと思いました。解決すべき問題がはっきりしているのでつくり甲斐がありました。

また、問題解決のアイデアを出すだけでなく動くものをつくるというのも大事かなと思いました。やっぱり動くものがあった方が議論が進むと思うんですよね。つくったものを見ながら議論を重ねる時間がもっと多かったら、さらにいいアイデアが出てきてよかったかな、と個人的には思ったりもしました。とはいえ短い時間ながら貴重なご意見やアイデアも出てきたので、何か次のアクションに活かせたらと思っています!

最後に、何の参考になるかわかりませんが、成果物を載せておきます!

2013年12月2日月曜日

今年の振り返り

2013年もあと一ヶ月となりましたので、今年の振り返りなどしてみようと思います。

今年の目標

「クラウドソーシャルを副業としてはじめてみる」

こんな目標を立ててました。結論から言うと達成できてません。ランサーズJob-Hubに登録こそしましたが受注案件はゼロ。よって売上もゼロ…。

でもいろいろやったよ

でも中長期目標である「地元秋田に帰る」を実現するために、色々やってきました。

秋田IT県人会に参加

秋田出身や秋田在住でITに関係する仕事、事業をやっている人たちの集まりに第一回から参加しました。
多くの方にお会いでき、また地元秋田で頑張っている方や東京で活躍されている方などが沢山いることを知ることができ、大変よい機会になりました。

あきた寺子屋に参加

秋田IT県人会のつながりで誘って頂き参加してきました。こちらでも地元を元気にしたいと起業やUターンを考えている方にお会い出来ました。同じ思いの人って結構いるもんだなと元気になりました。

転職活動

Aターンという秋田県の転職支援事業を活用し、1社採用面談を受けました。結果は最終面談まで進むも不採用。
私にとって魅力的な会社さえ見つかれば、給料のダウンは致し方がないとしても内定貰えるだろうという甘い考えが見事に打ち砕かれましたorz

妻と移住について話し合い

上記の転職が決まりかけたことで、妻と具体的な移住計画や移住後の生活などについて話し合いが出来ました。今まではふわっと同意してもらっていたものの、具体的なところ(親と同居が近居か、共働きになるのか、などなど)まで踏み込んで話せてよかったです。
双方腹をくくったところで不採用となりがっくりきてしまいましたw

サービスづくり

転職活動と並行して、副業で始めるサービスの開発をしていました。現在つめの作業中です。なかなかバグが解消せず公開できず歯がゆい日々が続いています…

まとめ

目標は未達だったものの、色々動けた一年だったかなと思います。今年蓄積したものをどうやって活用していくか、来年はもっと踏み込んだ一年にしようと思います!
ひとまず年内にサービス立ち上げまで持って行きたいですね…

2013年3月10日日曜日

Google+ Sign-in / Moment API

Google+ Platformの大きなアップデート、Google+ Sign-inが発表されました!詳細はニュース記事などに譲るとして、今回はとりあえずサインインしてAPIを呼び出すところまでやってみたのでまとめます。
こちらを参考に、ちょっと分からなかったところを補いつつ、Moment APIでApp Activityを送信するところまでやってみます。環境は、前回の記事で構築したものとなります。

準備その1:Client情報の登録

まずはGoogle+のClient IDとClient Srcretを取得します。公式ドキュメントのStep 1に従えばいいので省略します。

準備その2:必要なjarを配置

今回はMaven2で依存するjarを管理しているので、pom.xmlに設定を追加しておきます。WEB-INF/lib/にコピーも忘れずにしておきます。

  <repositories>
    <repository>
      <id>google-api-services</id>
      <url>http://google-api-client-libraries.appspot.com/mavenrepo</url>
    </repository>
  </repositories>

 ...

    <dependency>
      <groupid>com.google.api-client</groupid>
      <artifactid>google-api-client</artifactid>
      <version>1.13.2-beta</version>
    </dependency>
    <dependency>
      <groupid>com.google.api-client</groupid>
      <artifactid>google-api-client-servlet</artifactid>
      <version>1.13.0-beta</version>
    </dependency>
    <dependency>
      <groupid>com.google.api-client</groupid>
      <artifactid>google-api-client-appengine</artifactid>
      <version>1.13.2-beta</version>
    </dependency>
    <dependency>
      <groupid>com.google.apis</groupid>
      <artifactid>google-api-services-plus</artifactid>
      <version>v1-rev57-1.13.2-beta</version>
    </dependency>
    <dependency>
      <groupid>com.google.apis</groupid>
      <artifactid>google-api-services-oauth2</artifactid>
      <version>v2-rev9-1.7.2-beta</version>
    </dependency>

実装その1:CSRF対策

サインインボタンを表示するControllerを作成します。
この後説明するAccess Tokenの保存処理が不正に呼び出されないように、ランダムなパラメータを生成してセッションに保存しておきます。
同時に、Access Tokenの保存処理を呼び出すJavascriptにパラメータを渡せるように、リクエストにセットしておきます。

    @Override
    public Navigation run() throws Exception {
        String token = new BigInteger(130, new SecureRandom()).toString(32);
        sessionScope("validateToken", token);
        requestScope("validateToken", token);
        return forward("test.vm");
    }

実装その2:Javascriptライブラリの読み込み

Oauth2のAuthorization Code取得まではJavascriptでやるようなので、test.vmでGoogle+ライブラリを読み込んでおきます。
公式ドキュメントのStep 3のコピペでOKです。

実装その3:サインインボタンの設置

test.vmにサインインボタンを設置します。ここがポイントなのですが、
Moment APIを使う場合、data-requestvisibleactionsが必須になります。おそらくAPIの認可が必要ということなのでしょう。見事にハマったorz
他に指定できるパラメータはこちらに載っているのでご参照ください。

<div id="signinButton">
    <span class="g-signin"
        data-scope="https://www.googleapis.com/auth/plus.login"
        data-clientid="あなたのClient ID"
        data-redirecturi="postmessage"
        data-accesstype="offline"
        data-cookiepolicy="single_host_origin"
        data-callback="signInCallback"
        data-requestvisibleactions="http://schemas.google.com/AddActivity">
    </span>
</div>

実装その4:callback関数の実装

上記サインインボタンに設定したcallback関数を実装します。この中でAuthorization Codeを元にAccess Tokenを取得するリクエストを送信します。パラメータには、CSRF対策用のパラメータも設定します。

function signInCallback(authResult) {
    if (authResult['code']) {

        // Hide the sign-in button now that the user is authorized, for example:
        $('#signinButton').attr('style', 'display: none');

        // Send the code to the server
        jQuery.ajax({
            type: 'POST',
            url: '/api/storetoken',
            success: function(result) {
                
            },
            data: {
                code: authResult['code'],
                validateToken: '$validateToken',
            }
        });
    } else if (authResult['error']) {
        alert('Google+ Authorication Error');
    }
}

実装その5:Access Tokenの保存

JavascriptのPOSTを受けるControllerを実装します。まずはCSRF対策でパラメータチェックします。
その後、Authorization CodeとClient ID、Client Secretを使ってAccess Tokenを取得し、セッションに保存します。

    @Override
    public Navigation run() throws Exception {
        if (!validateToken()) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            Map<string string=""> data = new HashMap<string string="">();
            data.put("state", "403");
            return json(data);
        }

        String clientId = "あなたのClient ID";
        String clientSecret = "あなたのClient Secret";
        String code = asString("code");

        HttpTransport transport = new NetHttpTransport();
        JsonFactory jsonFactory = new JacksonFactory();
        GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(transport, jsonFactory,
            clientId, clientSecret, code, "postmessage"
        ).execute();
        GoogleCredential credential = new GoogleCredential.Builder()
            .setJsonFactory(jsonFactory)
            .setTransport(transport)
            .setClientSecrets(clientId, clientSecret).build()
            .setFromTokenResponse(tokenResponse);
        Oauth2 oauth2 = new Oauth2.Builder(transport, jsonFactory, credential).build();
        Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(credential.getAccessToken()).execute();
        if (tokenInfo.containsKey("error")) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            Map<string string=""> data = new HashMap<string string="">();
            data.put("state", "403");
            return json(data);
        }
        if (!tokenInfo.getIssuedTo().equals(clientId)) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            Map<string string=""> data = new HashMap<string string="">();
            data.put("state", "403");
            return json(data);
        }

        sessionScope("gPlusId", tokenInfo.getUserId());
        sessionScope("gAccessToken", credential.getAccessToken());

        Map<string string=""> data = new HashMap<string string="">();
        data.put("state", "200");
        return json(data);
    }

    protected boolean validateToken() {
        String specified = requestScope("validateToken");
        String token = sessionScope("validateToken");
        if (token.equals(specified)) {
            return true;
        }
        return false;
    }

    protected Navigation json(Object data) {
        try {
            JsonFactory jsonFactory = new JacksonFactory();
            JsonGenerator generator = jsonFactory.createJsonGenerator(response.getWriter());
            generator.serialize(data);
            generator.flush();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return null;
    }

実装その6:Moment API 呼び出し

最後に、取得したAccess Tokenを使ってMoment APIを呼び出すControllerを実装します。

    @Override
    public Navigation run() throws Exception {
        String gPlusId = sessionScope("gPlusId");
        String gAccessToken = sessionScope("gAccessToken");

        String clientId = "あなたのClient ID";
        String clientSecret = "あなたのClient Secret";
        String applicationName = "あなたのアプリ名";

        HttpTransport transport = new NetHttpTransport();
        JsonFactory jsonFactory = new JacksonFactory();
        GoogleCredential credential = new GoogleCredential.Builder()
            .setJsonFactory(jsonFactory)
            .setTransport(transport)
            .setClientSecrets(clientId, clientSecret).build()
            .setAccessToken(gAccessToken);

        Plus plus = new Plus.Builder(transport, jsonFactory, credential).setApplicationName(applicationName).build();

        Moment moment = new Moment();
        moment.setType("http://schemas.google.com/AddActivity");
        ItemScope itemScope = new ItemScope();
        itemScope.setId("target-id-1"); 
        itemScope.setType("http://schemas.google.com/AddActivity");
        itemScope.setName("The Google+ Platform");
        itemScope.setDescription("hogehoge!");
        moment.setTarget(itemScope);
        Moment momentResult = plus.moments().insert("me", "vault", moment).execute();

        MomentsFeed moments = plus.moments().list("me", "vault").execute();

        return redirect("/");
    }

自分の英語力不足なのか、公式ドキュメントからは分からなくてハマったところも多かったですが(Oauth2クラスとかTokenInfoクラスを使うのにどのjarが必要か、とか)、なんとか出来ました。
Client IDなどを設定ファイルにしたりなどリファクタリングもまだまだ必要ですが。
道具は揃ったので、これをどう使っていくか考えてみようと思ってます!

2013年3月1日金曜日

Slim3 + Velocity

Google App Engine for Javaを使いたくなり、評判の良さそうなフレームワークとしてSlim3を導入し、独断と偏見でJSPをやめてVelocityをテンプレートエンジンとして利用することにしました。
今回の内容は、その際の開発環境セットアップの備忘録となります。

開発環境

それぞれ現時点での最新版を使います。
  • Eclipse Classic 4.2.1 Mac OS X 64bit
  • Slim3 1.0.16
  • Velocity 1.6.2 + Velocity Tools 2.0

Slim3インストール

基本的にここを参考にEclipseにGoogle PluginとSlim3 Pluginをインストールします。ダウンロード先のURLがEclipseのバージョンに一致しているか確認します。今回は以下を使います。

https://dl.google.com/eclipse/plugin/4.2

http://slim3.googlecode.com/svn/updates/

Pluginのインストールが終わったら、Blankプロジェクトを作成します。Explorerで右クリック -> New -> Others -> Slim3と進めばOKです。上記Wikiに書いてあることのうち、workspaceの設定以外はPluginが勝手にやってくれます。

Velocityインストール

こちらを参考にさせて頂きました。が、いくつか補足。

まずは、http://velocity.apache.org/download.cgiからVelocity Toolsをダウンロード、解凍します。lib内にあるvelocity-1.6.2.jarとvelocity-tools-2.0.jar、それから依存関係のあるcommonsライブラリをコピーして、
先ほど作成したBlankプロジェクトのWEB-INF/lib/にペーストし、ビルドパスに追加します。

次に、src以下にVelocityViewServletを拡張したクラスを作成します。ひとまず以下のように実装しておけばOKです。

package test.hoge;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.Template;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.VelocityViewServlet;

public class VelocityServlet extends VelocityViewServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected Template handleRequest(HttpServletRequest request,
            HttpServletResponse response, Context ctx) {
        String uri = request.getRequestURI();
        String templatePath = getTemplatePath(uri);

        Enumeration attrNames = request.getAttributeNames();
        while(attrNames.hasMoreElements()) {
            String key = (String) attrNames.nextElement();
            ctx.put(key, request.getAttribute(key));
        }

        Template template;
        try {
            template = Velocity.getTemplate(templatePath, "UTF-8");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return template;
    }

    protected String getTemplatePath(String uri) {
        return "/WEB-INF/template" + uri;
    }
}

作成したら、このサーブレットを使用するようにweb.xmlに設定を追加します。

    <servlet>
        <servlet-name>VelocityServlet</servlet-name>
        <servlet-class>test.hoge.VelocityServlet</servlet-class>
       <init-param>
            <param-name>org.apache.velocity.toolbox</param-name>
            <param-value>/WEB-INF/velocity-tools.xml</param-value>
        </init-param>
        <init-param>
            <param-name>org.apache.velocity.properties</param-name>
            <param-value>/WEB-INF/velocity.properties</param-value>
        </init-param>
        <load-on-startup>10</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>VelocityServlet</servlet-name>
        <url-pattern>*.vm</url-pattern>
    </servlet-mapping>

これで、拡張子が.vmのものはVelocityServletを使用するようになります。velocity-tools.xmlとvelocity.propertiesはとりあえず空でいいので作成しておきます。

次に、appengine-web.xmlに以下を追加します。ついでにセッションは有効にしておきましょう。

 <sessions-enabled>true</sessions-enabled>
 <threadsafe>true</threadsafe>

    <static-files>
        <include path="**.js" />
        <include path="**.css" />
        <include path="**.png" />
        <include path="**.jpg" />
        <include path="**.jpeg" />
        <include path="**.swf" />
        <include path="**.gif" />
        <include path="**.ico" />
        <include path="**.html" />
    </static-files>
    <resource-files>
        <include path="**.jsp" />
        <include path="**.vm" />
    </resource-files>

Controller + .vmファイル作成

ここまで来たら、Antのgen-controller-without-viewでSlim3のControllerを作成します。JSPファイルの代わりに手動で.vmファイルをWEB-INF/template/に作成しましょう。.vmファイルの置き場所は拡張VelocityServletに書いてあるので、WEB-INF/の好きな場所に変えてしまってOKです。
Controllerと.vmの準備が出来たら、ローカル環境でサーバを起動してブラウザでアクセスできるか確認します。

ちなみに、Slim3 + Velocityの処理の流れは大まかに以下のようになっています。
  1. Controller#run()が呼ばれる
  2. **.vmにforward
  3. forwardで指定された拡張子が.vmなのでVelocityServletが起動
  4. pathで指定された.vmファイルがレンダリングされる
Velocityを入れるとJSPに比べればパフォーマンス劣るというのをちらっと見かけたのですが、とりあえず気にせずこの環境で色々作ってみようと思います。

2013年2月16日土曜日

meteor触ってみた

実は前々から気になっていたmeteorというWebフレームワークを、とりあえずサンプルを動かすまでやってみました。
先人に感謝しつつ、私のAirちゃんで動かしました。

セットアップ

まずはmeteorをインストールします。とはいえ、たったこれだけ。

$curl install.meteor.com | sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  5239  100  5239    0     0   8374      0 --:--:-- --:--:-- --:--:-- 12327
Installing Meteor to /usr/local/meteor

The install script needs to change the permissions on /usr/local so that
administrators can write to it. This may prompt for your password.

Password:
... downloading
######################################################################## 100.0%

Meteor installed! To get started fast:

  $ meteor create ~/my_cool_app
  $ cd ~/my_cool_app
  $ meteor

Or see the docs at:

  docs.meteor.com

これで/usr/local/bin/meteorコマンドが使えるようになったので早速。

$ meteor --help
Usage: meteor [--version] [--help]  []

With no arguments, 'meteor' runs the project in the current
directory in local development mode. You can run it from the root
directory of the project or from any subdirectory.

Use 'meteor create ' to create a new Meteor project.

Commands:
   run        [default] Run this project in local development mode
   create     Create a new project
   update     Upgrade to the latest version of Meteor
   add        Add a package to this project
   remove     Remove a package from this project
   list       List available packages
   bundle     Pack this project up into a tarball
   mongo      Connect to the Mongo database for the specified site
   deploy     Deploy this project to Meteor
   logs       Show logs for specified site
   reset      Reset the project state. Erases the local database.

See 'meteor help ' for details on a command.

サンプル

それではサンプルを動かしてみます。

$ meteor create --example leaderboard
leaderboard: created.

To run your new app:
   cd leaderboard
   meteor

プロジェクトを作成して、

$ cd leaderboard/
$ meteor
[[[[[ ~/workspace/test/meteor/leaderboard ]]]]]

Running on: http://localhost:3000/

これで起動します。さっそく表示されているURLにアクセスしてみます。


まあサンプルなのであんまり意味あるアプリじゃありませんが。

ソースコード

ソースコードはGitHubに上げました。


これから色々いじくってみたいと思います!