雑用係、来年もよろしくお願いしますm(_ _)m

文書を作る。
雑用係の仕事のひとつです。

法律用語とか雑用係にはよくわかりません。
仕事してる人なら当たり前に使うビジネス用語も使い分けに苦労します。
難しいです。
高卒の上に、高校ではデザインなんか勉強してたので、高3の頃なんか授業に理科系科目すらありませんでした(笑)

強いて言えば、本読みが好きなのと、小説家を目指していた黒歴史(´д`)があるので、一時期文章の勉強してたり、昔から割と平均的な読解力はあった方なので、なんとかやってます。

てことで。
言葉のマジックを少々。

この投稿の続きを読む »

Facebooktwitterlinkedintumblrmail

Jenkinsでphpcsする。

1.今回は、Jenkinsでphpcsを使う手順を書いていきます。
  最近CakePHPの仕事をやっているのでcakephp-codesnifferを使用します。

2.phing、phpcs、cakephp-codesnifferのインストール
  とりあえず、以下の作業はjenkinsユーザーで行いました。
  phing、phpcsのインストール
  phpcsはphingと一緒に入ります。

composer global require 'phing/phing:2.*'

  cakephp-codesnifferのインストール

composer global require 'cakephp/cakephp-codesniffer'

  全ユーザーでコマンドを使えるように/etc/profileに以下の行を追加
  (composer globalだと対象ユーザーのホームの.composerにインストールされます。)

export PATH="$PATH:/var/lib/jenkins/.composer/vendor/bin"

  phpcsでcakephp-codesnifferを使えるようにします。

/var/lib/jenkins/.composer/vendor/bin/phpcs --config-set installed_paths /var/lib/jenkins/.composer/vendor/cakephp/cakephp-codesniffer

  以下のコマンドでCakePHPが表示されればOKです。

phpcs -i

3.phingの設定
  Jenkinsの管理→システムの設定を押下
  Phingの追加を押下し、以下のように入力します。
5

4.Jenkinsのプラグインのインストール
  以下のプラグインをインストールします。
  Checkstyle Plugin
  Phing Plugin
  PHP Plugin
  Git Plugin

5.ジョブの実行手順
  ①gitでプロジェクトを取得
  ②phingでphpcsを実行

  プロジェクトの構成は以下のようになります。
4
  appがCakePHPのプロジェクトディレクトリで
  build.xmlがphingのbuildファイル
  buildディレクトリにphpcsの設定ファイルを入れています。

  phingのbuildファイルは以下のようにしました。
build.xml




    
    
    
    

    
    

    
    
        
            
            
            
            
        
    


  上記の設定の場合次のコマンドを実行するのと同じになります。

phpcs --standard=${basedir}/build/phpcs.xml --report=checkstyle --report-file=${logdir}/phpcs-report.xml ${appdir}

  変数を展開すると以下のような感じ

phpcs --standard=/var/lib/jenkins/jobs/phpcs-test/workspace/build/phpcs.xml --report=checkstyle --report-file=/var/lib/jenkins/jobs/phpcs-test/workspace/build/logs/phpcs-report.xml /var/lib/jenkins/jobs/phpcs-test/workspace

phpcsの設定ファイルは以下のようにしました。
phpcs.xml




    
    

    
    *database.php
    *i18n.php
    *core.php
    */app/Config/*
    */app/Console/*
    */app/Lib/*
    */app/Plugin/*
    */app/tmp/*
    */app/Vendor/*
    */app/webroot/*
    */app/Test/*
    */app/View/Helper/*
    

6.新規ジョブの作成
  新規ジョブ作成を押下します。
  ジョブ名を入力し、「フリースタイル・プロジェクトのビルド」を選択します。
  ソースコード管理を設定後、ビルド手順の追加で「Phingの呼出し」を選択します。
1
  使用するPhingでmyphingを選択
  Phingの呼出しに「phpcs」と入力します。
6
  設定ファイルとの関連は次のようになります。
7

7.試してみる
  以下のようにメソッドを追加してビルドを試してみます。

log('hoge', LOG_DEBUG);
}
}

以下のように出力されました。
8

コメントでhogeと@return voidの間に1行必要
hoge(){でhoge()と{の間にスペースが必要とでています。

難しい・・。

8.sublime-phpcsを使ってみる
  package controllでPhpcsをインストールします。
9

  ローカルで以下のコマンドを実行します。

composer global require 'phing/phing:2.*'
composer global require 'cakephp/cakephp-codesniffer'
~/.composer/vendor/bin/vendor/bin/phpcs --config-set installed_paths ~/.composer/vendor/bin/vendor/cakephp/cakephp-codesniffer

Preferences→Package Settings→PHP Code Sniffer→Settings – Userと開きます。
以下のように記述します。

{
"phpcs_executable_path": "/ユーザーのホームディレクトリ/.composer/vendor/bin/vendor/bin/phpcs",
    "phpcs_additional_args": {
        "--standard": "CakePHP"
    },
}

これでだめなところを表示してくれるようになりました。

11

Facebooktwitterlinkedintumblrmail

iOSでプッシュ通知時の挙動を確認したい

今回はiOSアプリを開発している際にプッシュ通知時の挙動を確認したい時に使えそうな「houston」というライブラリを紹介したいと思います。

nomad/houston

1. インストール

gem install houston

2. 送信用のrubyファイルを用意

ほぼREADMEにあったサンプルの通りのものです。
また、事前に開発用の「push_dev.pem」を同じディレクトリに置いています。

push.ruby

require 'houston'

# Environment variables are automatically read, or can be overridden by any specified options. You can also
# conveniently use `Houston::Client.development` or `Houston::Client.production`.
APN = Houston::Client.development
APN.certificate = File.read("push_dev.pem")

# An example of the token sent back when a device registers for notifications
token = "<《ここにプッシュ通知を送信したい端末のデバイストークンを指定します》>"

# Create a notification that alerts a message to the user, plays a sound, and sets the badge on the app
notification = Houston::Notification.new(device: token)
notification.alert = "ハロー, ワールド!"

# Notifications can also change the badge count, have a custom sound, have a category identifier, indicate available Newsstand content, or pass along arbitrary data.
notification.badge = 1
notification.sound = "sosumi.aiff"
notification.category = "INVITE_CATEGORY"
notification.content_available = true
notification.custom_data = {foo: "bar"}

# And... sent! That's all it takes.
APN.push(notification)

3. push通知を送信

ruby push.ruby

以上で、指定した端末にプッシュ通知が飛びます。
READMEにはデバイストークンの取得方法や証明書の作成方法なども載っておりすごく分かりやすいです。
この他にもコマンドラインからプッシュ通知を送信することが出来るようです。

apn push "<デバイストークン>" -c /path/to/apple_push_notification.pem -m "Hello from the command line!"
Facebooktwitterlinkedintumblrmail

GradleでAndroid部品を社内共有しよう!

1.はじめに
  Androidの開発をやっていると、前のプロジェクトで使った部品を次のプロジェクトでも
  使いたいなんてことがでてくると思います。しかし、公開されているリポジトリに
  登録できるような内容の部品じゃないということはよくあると思います。
  ということで、社内のリポジトリにGradleでAndroid部品を共有する内容を書いていきます。

2.手順
  ①gitlabにリポジトリを作成(社内ではgitlabを使っているため)
  ②ライブラリプロジェクトを作成し、AARをリポジトリに登録
  ③②のライブラリを使うプロジェクトの作成

3.gitlabにリポジトリを作成
  テスト的にこういう画像のカスタムビューを持つライブラリにします。
  ということでプロジェクト名は「Android-BaseLine」にしました。
  1

4.BaseLineライブラリを作成します。
  EclipseだとAARが使えないためAndroid Studioを使用します。

5.BaseLineViewはこんな感じ

package com.lancard.baseline;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

public class BaseLineView extends View {

    public BaseLineView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Paint paint = new Paint();
        paint.setColor(Color.rgb(0, 49, 236));
        //paint.setStrokeWidth(5);

        int height = getHeight();
        int width = getWidth();

        int y = 0;
        while(y

6.AAR作成用にbuild.gradleを書きます。
  ここのbuild.gradleになります。
2

元のソース

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.1"

    defaultConfig {
        applicationId "com.lancard.baseline"
        minSdkVersion 18
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

次のように書き換えます。

apply plugin: 'android-library'
apply plugin: 'maven-publish'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.1"

    defaultConfig {
        applicationId "com.lancard.baseline"
        minSdkVersion 18
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

android.libraryVariants
publishing {
    publications {
        maven(MavenPublication) {
            groupId 'com.lancard.lib'
            artifactId 'baseline-aar'
            version '1.0'
            artifact source: file("${project.buildDir}/outputs/aar/${project.name}-release.aar")
        }
    }
    repositories {
        maven {
            url "file:${projectDir}/maven-repo"

        }
    }
}

  <やっていること>
  ①apply plugin: 'com.android.application'→apply plugin: 'android-library'で
   アプリケーションプロジェクトからライブラリプロジェクトに
  ②apply plugin: 'maven-publish'を追加しMaven Publishプラグインを使えるようにする。
  ③ publishingを追加し、公開するファイルの設定をします。

  (ちなみにURLはリポジトリ管理ツールで運用されていれば
    直接転送できgit pushする必要はありません。)

7.Gradleのタスクを実行します。
  Maven Publishプラグインを使用すると、「maven(MavenPublication) 」の名前から
  publishMavenPublicationToMavenRepositoryというタスクができるので実行します。
3

  以下のようにmaven-repoというディレクトリができますので全て
  3.で作成したgitリポジトリにpushします。
4

  このようになったでしょうか。
5

8.BaseLineViewを使うプロジェクトを作成し、build.gradleを以下のように追記し、buildタスクを実行します。

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.1"

    defaultConfig {
        applicationId "com.lancard.hoge"
        minSdkVersion 18
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    lintOptions {
        abortOnError false
    }
}

repositories {
    maven {
        url "https://{社内gitlab}/{username}/android-baseline/raw/master/maven-repo"
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.lancard.lib:baseline-aar:1.0'
}

lintはとりあえず、オフにしています。

9.以下のように「com.lancard.baseline.BaseLineView」を使用するxmlを書いて実行できれば成功です。



    


10.バージョンがあがっていくとリポジトリはこのようになります。

6

11.SSLクライアント認証している場合
  社内のリポジトリがSSLクライアント認証している場合が多いと思います。
  SSLクライアント認証している場合は、gradleラッパーのJVMオプションで
  証明書のパスを設定する必要があります。
  プロジェクト配下にあるgradlewのDEFAULT_JVM_OPTSを以下のように書き換えます。

7

DEFAULT_JVM_OPTS=" \
-Djavax.net.ssl.keyStore=証明書のパス \
-Djavax.net.ssl.keyStoreType=pkcs12 \
-Djavax.net.ssl.keyStorePassword=証明書のパスワード \
"

  あとはgradleコマンドではなくgradlewを実行するようにします。

./gradlew build
Facebooktwitterlinkedintumblrmail

雑用係、OSX Yosemiteインストールに苦戦する

雑用係、生意気にもMac使いです(´∀`)

IMG_6637
※ 職場の机はMacBookAir11と私物のiPadAirでこんな感じ。自宅はPro15。某マンガ&アニメキャラは無視してね。

もちろん、Yosemiteがリリースされてからサクッとアップデートしました。
んまー、フラットデザインけっこーイケるわぁーなんてホクホクしてました。

でもって、あまり機械モノが得意じゃない友人にも毎度のことと「とりあえず無料だから、今回もちゃんとアップデートしとけよ〜」と言ってしまったのが、題目の原因です(×_×)

メッセがきました。
友人A「インストール失敗しました、って、でるんだけど」

でるんだけど、と言われましても、失敗したことないので、雑用係には原因が全くわかりません。そもそも、私は単なる雑用係であって我が社の精鋭技術者のようなスキルはないんですYO!

メッセや電話で、どういう状況なのか、あれやってみてー、これやってみてーとやれども、同様の状況になったことのない雑用係は、何が一体どうなってるのかサッパリぽんです(´・ω・`)

仕方ないので、休みの日に友人Aの家へ出向きました。
奮闘の始まりです(´д`)

この投稿の続きを読む »

Facebooktwitterlinkedintumblrmail

Node.jsを使ってチャット

Node.jsを使ってSocket.ioを用いたチャットルームを作成したいと思います

せっかくなので、前回紹介したYeomanを使って作成

generator-socketioというジェネレータがあるようなのでコレを使います。

まずはジェネレータのインストール

XXXXX:chat XXXXX$ sudo npm install -g generator-socketio
Password:

実行するディレクトリをつくったらyoで実行

今回はbootstrap使用、スタイルシートはCSSを使うことにします

XXXXX:workspace XXXXX$ mkdir chat
XXXXX:workspace XXXXX$ cd chat
XXXXX:chat XXXXX$ yo socketio

     _-----_
    |       |
    |--(o)--|   .--------------------------.
   `---------´  |    Welcome to Yeoman,    |
    ( _´U`_ )   |   ladies and gentlemen!  |
    /___A___\   '__________________________'
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

[?] What do you want to call this project? chat
[?] Write a brief description.
[?] What port number would you like to run on? 1337
chat
to run on port - 1337
[?] Do you want to use Bootstrap? Yes
true
[?] In what format would you like the Bootstrap stylesheets? css
css
   create server.js
   create views/index.ejs
   create public/js/app.js
   create Gruntfile.js
   create package.json
   create bower.json
   create .editorconfig
   create .jshintrc
   create .bowerrc
   create .gitignore

~~~

あとはgruntで実行するだけ。あーなんて楽ちん…

XXXXX:chat XXXXX$ grunt

-スクリーンショット 2014-11-24 23.15.25

あーbootstrap入れてなかった

Gruntfile.jsを確認した所、public/bowser_componentsにbootstrapファイルを

入れるといいみたいですね

XXXXX:chat XXXXX$ vi Gruntfile.js
~~~
    cssmin: {
      combine: {
        files: {
          'public/css/core.css': 'public/bower_components/bootstrap.css/css/bootstrap.css'
~~~

publicにbower_componentsディレクトリを作成し、公式サイトでDLしたbootstrapファイルを入れます

XXXXX:public XXXXX$ mkdir bower_components/
XXXXX:public XXXXX$ mkdir bower_components/bootstrap.css/

-スクリーンショット 2014-11-24 11.18.45

もう一回gruntで実行

おおーうまく行った!

-スクリーンショット 2014-11-24 23.14.16

すでに基本的なチャット機能が入っているようで、

もう一つブラウザを開いて文章のやりとりをしてみるときちんと動きます

せっかくなので、少し編集を加えてチャット部屋を用意してみることにします

TOP(localhost:1337)にアクセスしたらランダムなユーザ名と部屋IDを作成し、

各部屋(localhost:1337/id)に飛ぶイメージです

以下編集後

server.js 38行目〜

/*************************************
//
// chat app
//
**************************************/

// express magic
var express = require('express');
var app = express();
var server = require('http').createServer(app)
var io = require('socket.io').listen(server);
var device  = require('express-device');

var runningPortNumber = process.env.PORT;


app.configure(function(){
    // I need to access everything in '/public' directly
    app.use(express.static(__dirname + '/public'));

    //set the view engine
    app.set('view engine', 'ejs');
    app.set('views', __dirname +'/views');

    app.use(device.capture());
});


// logs every request
app.use(function(req, res, next){
    // output every request in the array
    console.log({method:req.method, url: req.url, device: req.device});

    // goes onto the next function in line
    next();
});

app.get("/", function(req, res){
    res.redirect('/'+ random_string(12));
});

app.get('/:room', function(req, res) {
    res.render('index', {room: req.params.room, name: random_string(5)});
});

io.sockets.on('connection', function (socket) {
    var room;    // 部屋ID
    var name;    // ユーザ名

    socket.emit('connected');

    socket.on('init', function(data) {
        room = data.room;
        name = data.name;

        socket.join(room);
        socket.broadcast.to(room).emit('blast', {msg:""+ name +" connected"});
    });

    socket.on('blast', function(data, fn){

        console.log(data);
        io.sockets.to(room).emit('blast', {msg:data.msg});

        fn();//call the client back to clear out the field
    });

    socket.on('disconnect', function() {
        socket.broadcast.to(room).emit('blast', {msg:""+ name +" disconnected"});
        socket.leave(room);
    });

});


server.listen(runningPortNumber);


/**
 * ランダムな文字列を返す
 */
function random_string(len) {
    var base = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    base = base.split('');
    var str = '';
    var count = base.length;
    for(var i=0; i

index.ejsはnameとroomを追加しただけ

views/index.ejs 52行目〜

                    

app.jsも同じくnameとroom追加

public/js/app.js 13行目〜

// shortcut for document.ready
$(function(){
    //setup some common vars
    var $blastField = $('#blast'),
        $allPostsTextArea = $('#allPosts'),
        $clearAllPosts = $('#clearAllPosts'),
        $sendBlastButton = $('#send'),
        $nameField = $('#name'),
        $roomField = $('#room');

    socket.emit('init', {name:$nameField.val(), room:$roomField.val()});

    $sendBlastButton.click(function(e){

        var blast = $blastField.val();
        var name  = $nameField.val();
        if(blast.length){
            socket.emit("blast", {msg:name +': '+ blast}, 
                function(data){
                    $blastField.val('');
                });
        }


    });

ここまで編集したらもう一回grunt実行

自動的に部屋へジャンプするようになりました

-スクリーンショット 2014-11-24 22.32.44

もう一つウィンドウを開き、同じURLにアクセスした後、

元の画面で確認すると部屋に別の人が入室したことを表示してくれています

-スクリーンショット 2014-11-24 23.05.40

もちろんチャットも出来ますし

ついでに退出を知らせる機能もあります

ウィンドウを消すと"●●● disconnected"と表示されることが確認できます

-スクリーンショット 2014-11-24 23.10.16

以上。らくちん。

Facebooktwitterlinkedintumblrmail

Yeomanを使ってみる

Yeomanがどういうものなのか詳しくは公式サイトを見ていただくとして、
要はWEBアプリを作る際の基本的な環境構築をパパっとやっちゃいますよ?というものです

気になっていたので、触ってみることにします

環境設定

Node.jsとnpmを入れていることが前提

Yeomanをインストール

$ sudo npm install --global yo bower grunt-cli

確認

$ yo --version && bower --version && grunt --version

Yeomanジェネレータをインストール

AngularJSGeneratorをインストール

$ sudo npm install --global generator-angular

プロジェクトフォルダ作成

$ mkdir yeoman
$ cd yeoman

実行すると今までインストールしたジェネレータのリストが出てくるので、必要な物をインストール

$ yo
? 'Allo XXXX! What would you like to do?
  Run a generator
  Angular
  Karma
  ──────────────
  Update your generators
  Install a generator
❯ Find some help
  Get me out of here!
  ──────────────

今回はAngular generatorを使いたいので、Angularを選択する。

$ yo
? 'Allo XXXX! What would you like to do? Angular

Make sure you are in the directory you want to scaffold into.
This generator can also be run with: yo angular


     _-----_
    |       |    .--------------------------.
    |--(o)--|    |    Welcome to Yeoman,    |
   `---------´   |   ladies and gentlemen!  |
    ( _´U`_ )    '--------------------------'
    /___A___\
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

Out of the box I include Bootstrap and some AngularJS recommended modules.

? Would you like to use Sass (with Compass)? (Y/n)

Saas使う?Bootstrap使う?モジュール使う?等聞かれるので、適時好きなように。今回はこのように選択しました。

? Would you like to use Sass (with Compass)? No
? Would you like to include Bootstrap? Yes
? Which modules would you like to include?
 ◉ angular-animate.js
❯◯ angular-aria.js
 ◉ angular-cookies.js
 ◉ angular-resource.js
 ◯ angular-messages.js
 ◉ angular-route.js
 ◉ angular-sanitize.js
 ◉ angular-touch.js

そしていつもどおりうまく行かない… 権限?

〜〜〜
npm WARN excluding symbolic link build/defs-config.json -> ../defs-config.json
npm ERR! Error: EACCES, mkdir '/Users/XXXX/.npm/debug/2.1.0'
npm ERR!  { [Error: EACCES, mkdir '/Users/XXXX/.npm/debug/2.1.0']
npm ERR!   errno: 3,
npm ERR!   code: 'EACCES',
npm ERR!   path: '/Users/XXXX/.npm/debug/2.1.0',
npm ERR!   parent: 'grunt-usemin' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.

色々トライしてみた結果キャッシュなくせばいいということだったらしい

$ npm cache clean

いけた!と思ったらこれ。npmが古いらしい。

〜〜〜
npm ERR! Error: ENOENT, open '/Users/XXXXX/Program/workspace/yeoman/node_modules/grunt/package.json'
npm ERR! If you need help, you may report this *entire* log,
npm ERR! including the npm and node versions, at:
npm ERR!     

npm ERR! System Darwin 13.4.0
npm ERR! command "/usr/local/bin/node" "/usr/local/bin/npm" "install"
npm ERR! cwd /Users/XXXXX/Program/workspace/yeoman
npm ERR! node -v v0.10.33
npm ERR! npm -v 1.4.28
npm ERR! path /Users/XXXXX/Program/workspace/yeoman/node_modules/grunt/package.json
npm ERR! code ENOENT
npm ERR! errno 34
npm ERR! not ok code 0

npmをもう一度入れなおして実行したらいけました

〜〜〜
└── js-yaml@2.0.5 (esprima@1.0.4, argparse@0.1.15)
app/index.html modified.


     _-----_
    |       |    .---------------------------------------.
    |--(o)--|    |        Bye from us! Chat soon.        |
   `---------´   |                                       |
    ( _´U`_ )    |            The Yeoman Team            |
    /___A___\    | https://github.com/yeoman/yeoman#team |
     |  ~  |     '---------------------------------------'
   __'.___.'__
 ´   `  |° ´ Y `

コレがファイル一覧

$ ls -al
total 88
drwxr-xr-x  15 XXXX  staff   510 11 14 10:00 .
drwxr-xr-x  36 XXXX  staff  1224 11 13 17:48 ..
-rw-r--r--   1 XXXX  staff    38 11 14 09:55 .bowerrc
-rw-r--r--   1 XXXX  staff   415  7  1 07:39 .editorconfig
-rw-r--r--   1 XXXX  staff    11  7  1 07:39 .gitattributes
-rw-r--r--   1 XXXX  staff    52  7  1 07:39 .gitignore
-rw-r--r--   1 XXXX  staff   394  7  1 07:39 .jshintrc
-rw-r--r--   1 XXXX  staff   110  5 15  2014 .travis.yml
-rw-r--r--   1 XXXX  staff  9815 11 14 09:55 Gruntfile.js
drwxr-xr-x  12 XXXX  staff   408 11 14 09:55 app
-rw-r--r--   1 XXXX  staff   414 11 14 09:55 bower.json
drwxr-xr-x  13 XXXX  staff   442 11 14 09:57 bower_components
drwxr-xr-x  29 XXXX  staff   986 11 14 10:00 node_modules
-rw-r--r--   1 XXXX  staff  1066 11 14 10:00 package.json
drwxr-xr-x   5 XXXX  staff   170 11 14 09:55 test

で、gruntを実行

$ grunt serve
Running "serve" task

Running "clean:server" (clean) task

Running "wiredep:app" (wiredep) task
Warning: ENOENT, no such file or directory '/Users/XXXX/yeoman/app/bower.json' Use --force to continue.

Aborted due to warnings.


Execution Time (2014-11-14 01:06:06 UTC)
loading tasks    6ms  ▇▇▇ 1%
wiredep:app    528ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 98%
Total 540ms

うーん・・・なんかbower.jsonのパスが違う

調べてみたところGruntfile.jsに少し編集をいれるといいらしい。
wiredepセクションのcwdを空にしました。

163     // Automatically inject Bower components into the app
164     wiredep: {
165       options: {
166 //        cwd: '<%= yeoman.app %>'
167         cwd: ''
168       },

で、もう一回トライ

$ grunt serve
Running "serve" task

Running "clean:server" (clean) task

Running "wiredep:app" (wiredep) task
app/index.html modified.

Running "concurrent:server" (concurrent) task

    Running "copy:styles" (copy) task
    Copied 1 files

    Done, without errors.


    Execution Time (2014-11-14 01:16:24 UTC)
    loading tasks  3ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇ 27%
    copy:styles    7ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 64%
    Total 11ms

Running "autoprefixer:dist" (autoprefixer) task
File .tmp/styles/main.css created.

Running "connect:livereload" (connect) task
Started connect web server on http://localhost:9000

Running "watch" task
Waiting...

いけた!!!
自動でブラウザが開かれます
-スクリーンショット 2014-11-14 10.24.11

Facebooktwitterlinkedintumblrmail

pChart2でグラフを描く

ロウソクチャートが使えるライブラリを探してみたところ、
pChart2というライブラリを見つけましたので紹介したいと思います
もともとあったpChartから更に扱えるグラフの種類が増えました

addPointsに配列で値を入力することで、グラフに値が描画されます
今回はDBから値を抜き出して配列にしているのですが、そこは省略しています
candle_chart

// グラフ生成
$dir = dirname(__FILE__) .'/../../public/pChart/';
include($dir .'class//pData.class.php');
include($dir .'class/pDraw.class.php');
include($dir .'class/pImage.class.php');
include($dir .'class/pStock.class.php');

/* Create and populate the pData object */
$MyData = new pData(); 
$MyData->addPoints($addOpen,"Open");
$MyData->addPoints($addClose,"Close");
$MyData->addPoints($addMin,"Min");
$MyData->addPoints($addMax,"Max");

$MyData->addPoints($addDate,"Time");
$MyData->setAbscissa("Time");
$MyData->setAbscissaName("Date");

/* Create the pChart object */
$myPicture = new pImage(700,330,$MyData);

/* Turn of AAliasing */
$myPicture->Antialias = FALSE;

/* Draw the border */
$myPicture->drawRectangle(0,0,699,329,array("R"=>0,"G"=>0,"B"=>0));

$myPicture->setFontProperties(array("FontName"=>$dir ."fonts/pf_arma_five.ttf","FontSize"=>6));

/* Define the chart area */
$myPicture->setGraphArea(60,30,650,290);

/* Draw the scale */
$scaleSettings = array("GridR"=>200,"GridG"=>200,"GridB"=>200,"DrawSubTicks"=>TRUE,"CycleBackground"=>TRUE);
$myPicture->drawScale($scaleSettings);

/* Create the pStock object */
$mystockChart = new pStock($myPicture,$MyData);

/* Draw the stock chart */
$stockSettings = array(
    "BoxUpR"=>226,"BoxUpG"=>159,"BoxUpB"=>149,
    "BoxDownR"=>180,"BoxDownG"=>188,"BoxDownB"=>201,
    'BoxUpBorderR'=>220,'BoxUpBorderG'=>75,'BoxUpBorderB'=>66,
    'BoxDownBorderR'=>127,'BoxDownBorderG'=>142,'BoxDownBorderB'=>166,
    );
$mystockChart->drawStockChart($stockSettings);

/* Render the picture (choose the best way) */
$myPicture->Stroke();

line_chart

$dir = dirname(__FILE__) .'/../../public/pChart/';
include($dir .'class/pData.class.php');
include($dir .'class/pDraw.class.php');
include($dir .'class/pImage.class.php');

$MyData = new pData(); 
$MyData->addPoints($addPoint,"Stock price");
$MyData->addPoints($addDate,"Labels");
$MyData->setSerieDescription("Labels","Months");
$MyData->setAbscissa("Labels");


/* Create the pChart object */
$myPicture = new pImage(700,330,$MyData);

/* Turn of Antialiasing */
$myPicture->Antialias = FALSE;

/* Add a border to the picture */
$myPicture->drawRectangle(0,0,699,329,array("R"=>0,"G"=>0,"B"=>0));

/* Set the default font */
$myPicture->setFontProperties(array("FontName"=>$dir ."fonts/pf_arma_five.ttf","FontSize"=>6));

/* Define the chart area */
$myPicture->setGraphArea(60,40,650,300);

/* Draw the scale */
$scaleSettings = array("XMargin"=>10,"YMargin"=>10,"Floating"=>TRUE,"GridR"=>200,"GridG"=>200,"GridB"=>200,"DrawSubTicks"=>TRUE,"CycleBackground"=>TRUE);
$myPicture->drawScale($scaleSettings);

/* Turn on Antialiasing */
$myPicture->Antialias = TRUE;

/* Draw the line chart */
$myPicture->drawLineChart();

/* Write the chart legend */
$myPicture->drawLegend(540,20,array("Style"=>LEGEND_NOBORDER,"Mode"=>LEGEND_HORIZONTAL));
$myPicture->Stroke();

JpGraghとくらべても見栄えが良く、カスタマイズ性にも富んでいます
ただこのpChart2、更新がだいぶ前からされていないようなので、
その辺を注意して使わないといけないようです

Facebooktwitterlinkedintumblrmail

Nginxのリバースプロキシを設定していてlocationの優先順位で大ハマリ

社内システムを動かしていたApacheなサーバーが廃止されたのでNginxなサーバーに移行しました。

他の社内システムに相乗りして、URLに特定のサブディレクトリがついていたら動作を分けて背後のアプリケーション・サーバーにリバースプロキシで接続という構成です。

server {
    #省略

    #リバースプロキシの設定を追加
    location /hoge/ {
        proxy_pass http://127.0.0.1:3000/;
    }

    #省略

    location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
        access_log        off;
        log_not_found     off;
    }
}

Nginxに上記のようなリバースプロキシの設定を入れたところプログラムは動作しているのに画像、css、jsが読み込めずに大ハマリしました。

勘がいい人は「他は省略しているのに残してある箇所」があやしいのに気づいてしまったと思いますが、その通り、アクセスログにも何も出ない、なぜだ?なぜなんだぜ?と調べていたらいらっしゃいましたよ、画像、css、jsの処理を全部もっていってるお方が。

location、正規表現の方が未指定の前方検索より強いので location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ に処理を全部もっていかれていたってわけです。Nginx で location の判定方法と優先順位を調べるがとても参考になりました。ありがとうございます。

正規表現よりも優先順位が高い書き方で指定すると解決しました。

server {
    #省略

    #リバースプロキシの設定を追加
    location ^~ /hoge/ {
        proxy_pass http://127.0.0.1:3000/;
    }

    #省略

    location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
        access_log        off;
        log_not_found     off;
    }
}
Facebooktwitterlinkedintumblrmail

一つのVagrantfileで複数VMを管理する際のメモ

下記のようなVagrantfileで複数VMを管理している際に「vagrant halt」を行うと…

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.define :first do |first|
    first.vm.box = "centos6.5.3"
    first.vm.network :forwarded_port, guest: 80, host: 8080
    first.vm.network :private_network, ip: "192.168.33.10"
  end
  
  config.vm.define :second do |second|
    second.vm.box = "centos6.5.3"
    second.vm.network :forwarded_port, guest: 80, host: 8181
    second.vm.network :private_network, ip: "192.168.33.11"
  end
end

2つとも停止します。

~/w/vagrantTest ❯❯❯ vagrant halt
 second: Attempting graceful shutdown of VM...
 first: Attempting graceful shutdown of VM...

片方だけ停止したい場合には「vagrant halt first」のように引数にマシン名を指定すれば良いのですが
停止したくないマシンまで誤って停止させるのを避けたかったので、何か良い方法はないか調べました。

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  if ARGV[1] == "first" # 追加
  config.vm.define :first do |first|
    first.vm.box = "centos6.5.3"
    first.vm.network :forwarded_port, guest: 80, host: 8080
    first.vm.network :private_network, ip: "192.168.33.10"
  end
  end # 追加
  if ARGV[1] == "second" # 追加
  config.vm.define :second do |second|
    second.vm.box = "centos6.5.3"
    second.vm.network :forwarded_port, guest: 80, host: 8181
    second.vm.network :private_network, ip: "192.168.33.11"
  end
  end # 追加
end

このようにすると「vagrant halt」だけでは停止しなくなり、マシン名を指定することで停止出来るようになります。

Facebooktwitterlinkedintumblrmail