Make Local Happiness

自分の幸せは自分で作る!!!

ValueDomainで取得したドメインをロリポップで利用したい時のDNS設定

普通にロリポップDNSサーバに移管すれば、面倒な設定もいらないのですが、 ロリポップだけではサブドメインの設定ができませんでした。
方法としてはムームードメインで管理しているドメインであれば、 DNSの設定ができるようでした。

ValueDomainもムームードメインも同じGMOなのに。。 悲しいです。

移管の手続きも時間が掛かりそうなので、 ValueDomain上で設定することにしました。

ムームードメインドメインを取得していればこのような設定は必要ないです。
ロリポップ使うなら、ムーム使えよってことですね。

ValueDomain上でネームサーバの確認

最初はロリポップのネームサーバを利用していたので、 ValueDomainのネームサーバに戻します。

ネームサーバ変更の画面を見ると、下に「当サービス内のネームサーバー(ns1~5.value-domain.com)を利用する」のリンクがあるのでクリックすると設定されます。

f:id:iwate_takayu:20161206143644p:plain

DNS設定

ホームページ、ロリポップのメール、サブドメインが使えるようにしたいので、 その設定を書きます。

ホームページの設定

最初にホームページですが、 「ロリポップ!のドメイン」というのが基本情報に書かれているので、 そのドメインに対して「nslookup」コマンドでIPを調べます。

$ nslookup example.oops.jp
Server:     8.8.4.4
Address:    8.8.4.4#53

Non-authoritative answer:
Name:   example.oops.jp
Address: xxx.x.xxx.xxx

調べたIPアドレスDNS設定画面でAレコードで追加します。
@マークが(サブドメインなし)の設定になります。
wwwも追加しておきましょう。

a @ 調べたIPアドレス
a www 調べたIPアドレス

メールの設定

ロリポップのメールサーバを設定します。
Aレコードも追加するので、IPも調べておきます。
ロリポップのメールサーバのドメインは「mx01.lolipop.jp」だったので先程と同じように調べます。

$ nslookup mx01.lolipop.jp
Server:     8.8.4.4
Address:    8.8.4.4#53

Non-authoritative answer:
Name:   mx01.lolipop.jp
Address: 157.7.107.6

MXレコードでロリポップのメールサーバを指定して、 AレコードでメールサーバのIPアドレスを設定します。

mx mx01.lolipop.jp. 10
a mx1 157.7.107.6

サブドメインの設定

実は、今回はGithub Pagesで作ったサイトをサブドメインで設定したかったのでした。
「192.30.252.153、192.30.252.154」をAレコードで追加します。

a sub-domain-name 192.30.252.153
a sub-domain-name 192.30.252.154

確認

確認はサイトをブラウザで確認してもいいですし、 digコマンドでもチェックできます。
※今回はメールがなかなか切り替わらず、何度もdigで確認してました。

$ dig yahoo.co.jp MX

; <<>> DiG 9.8.3-P1 <<>> yahoo.co.jp MX
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19979
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;yahoo.co.jp.           IN  MX

;; ANSWER SECTION:
yahoo.co.jp.        501 IN  MX  10 mx5.mail.yahoo.co.jp.
yahoo.co.jp.        501 IN  MX  10 mx1.mail.yahoo.co.jp.
yahoo.co.jp.        501 IN  MX  10 mx2.mail.yahoo.co.jp.
yahoo.co.jp.        501 IN  MX  10 mx3.mail.yahoo.co.jp.

;; Query time: 15 msec
;; SERVER: 8.8.4.4#53(8.8.4.4)
;; WHEN: Tue Dec  6 14:58:52 2016
;; MSG SIZE  rcvd: 114

【映画】エンジニアに見て欲しいオススメの3選

最近Netflix契約しました。 ナルコスのCMがFacebookでよく出てきたので、気になって契約してしまいました。 ナルコス自体は結構過激で見ていて正直気分はあまり良くなかったですが、 迫力のあるドラマでした。

今回は私の好きなエンジニア関係の映画を3つご紹介します。 たまには映画でも見てゆっくりした休日を過ごすととっても幸せな気分になれます。

1. The Social Network

最初はソーシャルネットワークです。
Facebookの創業物語を映画にした作品です。 もう10回くらい見たと思うのですが、それくらい好きです。

この物語の中で、一番好きなシーンは、 西海岸に仲間を選抜するときのシーンです。

youtu.be

挑戦するエンジニアは10分以内にWebサーバーへ侵入して管理者権限を奪うのを競争するのですが、
プログラムを10行書くたびに、お酒を一杯飲まなければならなかったり、
3分たったらお酒を一杯飲まなければならないなど、結構無茶くちゃなことしています。

でも、あの盛り上がり、熱量がほんと最高だと思いました。

さらに最後に2人がクリアできて、
ザッカーバーグ

「Welcome to Facebook!」

と言っているシーンが、
とても、希望にあふれていて、一番幸せな瞬間に感じました。

これから物語が動き出す。始まる感じです。

もう一つ好きなシーンを上げるなら、
ナップスターという個人間で音楽を共有できるサービスを作った、
ショーン・パーカー」と「ザッカーバーグ」が初めて会うシーンです。

盛大に遅刻し、
店員と華麗に話し、
ナップスターの出来事を身振り手振りで語り、
その姿はまさにちょいワルなカッコイイ大人です。

最後にThe Facebookというサービス名の「The」を取れと言うショーンのクールさはしびれます。

2. The Internship

この映画は時計販売会社のやり手中年セールスマンのビリーとニックのコンビが、 ある日突然会社が倒産し失業。

途方にくれていたが、 Googleインターンで正社員を目指し人生の一発逆転を狙う話しです。

この2人のコントというか、ギャグは最高です。

息ぴったり!

でまかせばっかり言うのですが、
そのノリの良さで思わず笑っています。

しかし、同じインターンを受ける学生やインターン試験官からは厳しい目で見られます。

この2人はエンジニアでもITに詳しくもない時計販売のセールスマンなので、当たり前なのです。

ですが、持ち前の明るさとノリで、周りを巻き込み、 チームとして戦うことを教えてくれます。

何度でもやり直せる。挑戦できる。ということをこの映画を見て思いました。

youtu.be

3. 3 Idiots (きっとうまくいく)

この映画ほど笑って泣ける映画はありません。 エンジニア以外の人が見てもとてもおもしろい映画だと思います。

この映画は、インドの超エリート大学ICEでの大学生活が舞台です。 学生達は卒業したらエンジニアになるために必死に勉強しています。

そんな中、主人公のランチョーは自分の好きなことを自由に学んでいる異端児で、 「好きなことをやるべきだと」いいます。

ただ、好きなことをやるには、逆境がつきもので、 例えば、学長に逆らう必要があったり、親の希望を裏切る必要があったりします。
そんなときに、ランチョーは「アーリーズウェル(きっとうまくいく)」と言います。
これはおまじないで、 心はとても臆病だから麻痺させる必要がある時にこの言葉を言うのだそうです。

この映画から私は勇気と元気をもらいました!!
仕事についても、将来どうしようと考えている学生や転職を考えている人がいたら是非身て欲しいです。

www.youtube.com

左ききのエレンが凄い!!

cakes.mu

かっぴーさんという方が書いた、 「左ききのエレン」はFacebookのタイムラインによく出てくるので、 ずっと気になっていたんですが今日Amazonでポチっとしてしまいました。

cakesで連載しているのですが、
左ききのエレンしか知らなかったので、有料会員になるのはやめました。 今後面白い作品が増えて来たら会員になるかも。

天才になれなかった全ての人へ

タイトルは左ききのエレンの表紙の言葉です。 このタイトルだけでもかなりビビビっときます。

広告代理店でクリエイティブとして働く光一と、 タイトルにもあるエレンが主人公です。

エレンは2巻まで読んでも現在、世界的に有名なデザイナーくらいしかわからなく、 謎に包まれています。

かっぴーさん自信も美大を卒業し、 大手広告代理店のアートディレクターとして働いた経験がにじみ出てる作品です。

なんか、読んでると焦ります。

早く3巻読みたい。

3.xのバブルチャートを4系に書き換えてみる

f:id:iwate_takayu:20161005215354p:plain

昨日に引き続き3.x系のサンプルを4系に書き直して行こうと思います。 当分はネタがない時はこれで行こうかと思っています。 Gistページの人気順に4系にしていきたいと思います。

完成品 Bubble Chart in v4 - bl.ocks.org

バブルチャート

バブルチャートとは分類毎のデータを円の大きさで表すグラフです。 軸が1つしかない分ぱっと見てわかりやすいんですが、 使い所が難しそうなチャートですね。

円の大きさと色の濃さで軸を変えてもいいですが、
その場合は余計にわかりづらくなるので、1軸で使うのがいいかと思います。

ただ、バブルチャートもインタラクティブに軸を変更できると、 表現力の低さは補えます。

こちら古いですが、
オバマ大統領の2013年度の予算案はとてもわかりやすく見ることができます。

http://www.nytimes.com/interactive/2012/02/13/us/politics/2013-budget-proposal-graphic.html?_r=0

実装

変更点はこちらです。

  • index.html 17行目
    d3.schemeCategory20cは関数ではなく、ただの配列になったので、 Scaleを追加する必要があります。
color = d3.scale.category20c();
↓  
color = d3.scaleOrdinal(d3.schemeCategory20c);
  • 19行目 3系でd3.layout.XXX系の関数名は間にlayoutがなくなりました。 sortも階層型のデータを作る関数のd3.hierarchy側でやるようになりました。
var bubble = d3.layout.pack()
    .sort(null)
    .size([diameter, diameter])
    .padding(1.5);  
↓
var bubble = d3.pack()
    .size([diameter, diameter])
    .padding(1.5);
  • 31行目 d3.packで取り込める形にデータを加工していきます。
  var root = d3.hierarchy(flatten(data))
      .sort(null)
      .sum((d) => d.value);

まとめ

Bubble Chart in v4 - bl.ocks.org

今回も3系と表示が変わってしまいました。
時間がある時に調べてみたいと思います。
他は簡単なチャートなので実装では特に詰まるところはなかったです。

55行目のflatten関数はネストされたデータを平らにしているのですが、 d3.flattenのような関数であってもいいかもなと思いました。

今日気づいたのですが、GistもForkできるんですね。
表示されているけど、昨日まで気づかなかった。。
今回のGistではForkしました。

Forking and cloning gists - User Documentation

また、GistのコードはGithubカレンダーには反映されないですね。。
これは結構かなしいですね。
対応してくれないか聞いてみようかな。

D3.jsが4.xになったので、3.xのツリーマップを書き換えてみる

f:id:iwate_takayu:20161004235735p:plain

最近d3.js がver4がリリースされました。 4系になり、モジュール化され各機能が切り分けられました。

多分、データの描画以外のために、機能毎に使えるようになり、 また、拡張がしやすくなったのだと思います。

ただ、、3系との互換性はまったくありません。 Exampleページの多くは3系のままで、 4系のサンプルがまだ少ないため、3系のサンプルを4系に修正していこうと思います。

今回はツリーマップを4系に修正していきます。

完成版はこちらです。

Treemap in v4 - bl.ocks.org

d3.js とは?

Data Driven Documentの頭文字をとってd3です。データに基づいてドキュメントを操作するための JavaScript ライブラリです。 Mike Bostockさんが作ってくれています。

D3 (or D3.js) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, Canvas and HTML. D3 combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data.

4系で何がかわったのか?

d3/CHANGES.md at master · d3/d3 · GitHub

こちらの変更ログをみてもらうとわかるのですが、 かなりの量の変更がありました。

1番大きな変更点としては、 冒頭でも書いたとおり、モジュール化され、D3は1つのライブラリなのですが、 沢山の小さなライブラリーの集合体になりました。

また、メソッド名も短くなり読みやすくなりました。

For example, with v3.x, to specify top orientation and scale for your visualization axis in d3, this was the way to go d3.svg.axis().scale(xscale).orient(“top”). Now, this has been changed to d3.axisTop(xscale)

TreeMapを書き換えてみる

ためしに、こちらのツリーマップを書き換えてみました。 Treemap - bl.ocks.org

私が作ったのはこちらです。 Treemap in v4 - bl.ocks.org

データの作り方が変わっていたり、 callでthisが呼ばれなかったりと、幾つかハマりポイントがありました。

また、ソート順が変わっているのか、 Ver3と全く同じグラフは表示できませんでした。 ここはおいおい、調査していきます。

検索でもどのサンプルが4系なのかわからなかったりするので、 4系だけ集めたリンク集があったらいいですね。

AWSのLambda上でSVGをPNG画像に変換する〜Phantomjs編〜

前回はFabricを利用し、LambdaでSVGPNG画像に変換するということを試しましたが、 今回はPhantomjsを使って同じことをやっていきます。

ganeza.hatenablog.com

Phantomjs とは?

http://phantomjs.org/

簡単に言うとディスプレイ不要のJavascriptAPIを備えたWebkit実行環境です。 ネイティブブラウザと同じようにDOM操作、CSSセレクター、JSONCanvasSVGもサポートしています。

PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.

主な使い方として、以下の4つが公式ページに記載されています。

  • HEADLESS WEBSITE TESTING
  • SCREEN CAPTURE
  • PAGE AUTOMATION
  • NETWORK MONITORING

今回は2番目のスクリーンキャプチャの機能を使って、 SVGPNG画像に変換していきます。

実装

コードを見てもらうとわかるのですが、 Fabric編のコードよりもさらに簡単になりました。 svg2pngというPhantomjsを利用したパッケージを使っていますが、 CLIでも試すことができ、かなり便利でした。

github.com

さらに、Fabricで描画されなかったforeignObjectも表示されました。
これはかなり嬉しいです。

#hander.js

'use strict';

const aws = require('aws-sdk'),
  s3 = new aws.S3({ apiVersion: '2006-03-01' }),
  md5 = require('md5'),
  svg2png = require("svg2png"),
  env = require('./env.js'),
  hash = md5(new Date().getTime()),
  imageKey = `${hash}.png`,
  phantomjsCmd = './phantomjs';

module.exports.convert = (event, context) => {
  const params = event.body;

  if (params === undefined) {
    return context.done(null,{
      status: 'error',
      msg: 'you should check params.',
      your_params: event,
      sample_params: {
        "body": {
          svgString: 'xxx',
        }
      }
    });
  }

  const svgString = decodeURIComponent(params.svgString);
  const sourceBuffer = new Buffer(svgString);
  const options = params.local ? {} : { phantomjsPath: phantomjsCmd };

  svg2png(sourceBuffer, options)
    .then(buffer => {
      s3.putObject(
        {
          'Bucket': env.BUKKET,
          'ACL': 'public-read',
          'Key': imageKey,
          'ContentType': 'image/png',
          'Body': buffer
        },
        function (error) {
          if(error === null) {
            return context.done(null,{
              status: 'success',
              msg: `https://s3-${env.REGION}.amazonaws.com/${env.BUKKET}/${imageKey}`,
            });
          } else {
            return context.done(null, {
              status: 'error',
              msg: error
            });
          }
        }
      );
    })
    .catch(e => {
      return context.done(null, {
        status: 'error',
        msg: e
      });
    });
};

【問題1】svg2pngがES6の記法で書かれており、LambdaではES6の記法が使えない

このFunctionの初期値の設定で利用している部分の書き方でエラーになっていました。

なので、Lambdaで使いたいから修正をPullRequestで送ったのですが、 古い書き方に対応するつもりはないよって言われあっさり断られました。

なので、Forkしたプロジェクトをnpmで利用することにしました。

github.com

【問題2】MacでビルドしたPhantomjsのモジュールではLambda上では動作しない

svg2pngのoptionsにパラメータを渡した際に、
Phantomjsのパスを変更できるように変更しました。

こちらの修正も先程のPullRequestに含まれています。

Linux用のモジュールはこちらからダウンロードできます。

$ wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
$ tar -xjvf ./phantomjs-2.1.1-linux-x86_64.tar.bz2
$ mv phantomjs-2.1.1-linux-x86_64/bin/phantomjs ./

まとめ

画像処理系のパッケージは環境依存のライブラリーを使うので、 Lambdaで使う際には少し面倒くさいですね。

Phantomjsは今回初めて使いました。
今まで、テストで使うものと思っていましたが、 コマンドライン上で動くブラウザと考えると色々なことができそうですね。

AWSのLambda上でSVGをPNG画像に変換する〜Fabric編〜

f:id:iwate_takayu:20161003000656p:plain

最近いくかの案件でSVGを画像に変換したいことがありました。
d3.jsでグラフを表示した後に、その状態の画像をパワーポイントに貼り付けたかったり、 メールなどでレポートしたいことがあると思います、 そんな場合に、サーバでSVGを画像に変換できるととても便利です。

しかも、EC2ではなく、スポットで動くLambdaでできるとサーバ代も安く抑えられていいかと思います。

今回はAPISVGのデータを送って、 SVGCanvasに変換しPNGに書き出すということをやっていきます。

SVGCanvasPNG

SVGPNG画像に変換する方法

方法としては、Fabric.js(Canvas)を使う方法と、 Phantomjs、Graphicsmagickなど幾つかやり方があります。

Fabric.jsとは?

Canvasを簡単に活用できるためのフレームワークです。ただのCanvasモジュールでも同じことができるのですが、 今回はこちらの方が簡単そうでした。

Fabric.js is a framework that makes it easy to work with HTML5 canvas element. It is an interactive object model on top of canvas element. It is also an SVG-to-canvas parser.

実装してみる

github.com

コードはこちらから見ることができます。 実装の流れとしては、以下のようになります。

1, SVGエンコードしたものを、 一旦JsdomでHTMLに変換します。

2, FabricでCanvasオブジェクトを作成

3, SVGCanvasに追加し、バイナリーに変換

4, バイナリーをPNG形式でS3にアップロード

# hander.js

'use strict';

const aws = require('aws-sdk'),
  s3 = new aws.S3({ apiVersion: '2006-03-01' }),
  fabric = require('fabric').fabric,
  jsdom = require("jsdom"),
  md5 = require('md5'),
  env = require('./env.js');

module.exports.convert = (event, context, cb) => {
  const params = event.body;
  const svgString = jsdom.jsdom(decodeURIComponent(params.svgString)).body.innerHTML;
  const width = params.width;
  const height = params.height;

  const canvas = fabric.createCanvasForNode(width, height);

  fabric.loadSVGFromString(svgString , (objects, options) => {
    options.top = 0;
    options.left = 0;
    const svgGroups = fabric.util.groupSVGElements(objects, options);
    canvas.add(svgGroups).renderAll();
    const binaryData = canvas.nodeCanvas.toBuffer();
    const hash = md5(new Date().getTime());
    const imageKey = `${hash}.png`;

    s3.putObject(
      {
        'Bucket': env.BUKKET,
        'ACL': 'public-read',
        'Key': imageKey,
        'ContentType': 'image/png',
        'Body': binaryData
      },
      function (error) {
        if(error === null) {
          return cb(null,{
            status: 'success',
            msg: `https://s3-${env.REGION}.amazonaws.com/${env.BUKKET}/${imageKey}`,
          });
        } else {
          return cb(null, {
            status: 'error',
            msg: error
          });
        }
      }
    );
  });
};

実行してみる

簡単にSVGPNGに変換することができます。

$ serverless invoke -f lambdaSvgToPngFabric -p event.json
{
    "status": "success",
    "msg": "https://s3-ap-northeast-1.amazonaws.com/xxxxx/13808df0bd74460d995ce033620385dd.png"
}

Canvasのモジュールはローカルで動いても、Lambda上では動かない

実装中にハマったポイントとしては、Canvasのモジュールのビルドです。
開発環境はMacなのですが、 MacでビルドしたCanvasのモジュールは、Lambda上では動きません。 以下のようなエラーがでます。

{
    "errorMessage": "/var/task/node_modules/contextify/build/Release/contextify.node: invalid ELF header",
    "errorType": "Error",
    "stackTrace": [
        "Object.Module._extensions..node (module.js:434:18)",
        "Module.load (module.js:343:32)",
        "Function.Module._load (module.js:300:12)",
        "Module.require (module.js:353:17)",
        "require (internal/module.js:12:17)",
        "bindings (/var/task/node_modules/bindings/bindings.js:76:44)",
        "Object.<anonymous> (/var/task/node_modules/contextify/lib/contextify.js:1:96)",
        "Module._compile (module.js:409:26)",
        "Object.Module._extensions..js (module.js:416:10)"
    ]
}

なので、一旦以下のサイトの手順で、 node_modulesに必要なlibと、Lambda用にビルドする必要があります。 github.com

まとめ

canvasのモジュールをビルドするところ意外は特に問題なくできました。

ただ、この記事では触れていませんが、 SVG内でDivタグを描画する際に使うforeignObjectが描画できませんでした。。 なので、次はPhantomjsで試してみようと思います。