かざいむ日誌

IT関係で知ったことなどを記事としてあげていきます。内容に不備や質問などあればぜひコメントをよせてください。

提案書もgitで管理するとやる気が出る。

今、次のお仕事に向けて提案書を書いているが、最初の方は全然筆が進まなくて、生活のリズムがやや崩れていた。で、それでもなんとかやっていたんだけど、途中からまた進まなくなったので、テスト前の掃除の要領で、書類をgitで登録して、ブランチ切って、diffで触ったところを時々確認しながら進めてみた。

これが結構良い感じ。ブランチは元々慣れてないのでスコープの違う作業もたまにしてるけど、フォーカスがはっきりするのであまり寄り道せずに済む。例えば、事例の記述、でブランチを切って、それが終わったらmasterにマージした。

で、ちょっと煮詰まると、git diffで自分の触ったところを確かめるとこれがまたちょこちょこ赤くなっててうれしい。

出来ればもう少しブランチの順序をはっきりさせて、定期的にgit diffの結果がポンと出てくるとおしり叩かれてる感じがして良いんだけど、なんかいいツールないかな。

Ruby on Rails Tutorial で微妙に引っかかるところ。

TutorialではCloud9を利用する想定で書かれているが、VMWare上にUbuntuを立てて動かすとちょっとはまったところがいくつかあったのでメモ。

 

サンプルのままRailsを実行するときに環境変数が設定されてなくてサイトが開けない。

以下のコマンドでRailsを動かす。

rails server -b ${IP:-127.0.0.1} -p ${PORT:-3000}

 

Herokuではconfigなどのファイルで1行めにあるruby2.2が引っかかるためrubyに書き換える。

 

最初のテストを動かそうとしたら、エラー。

var/lib/gems/2.2.0/gems/railties-5.0.0.1/lib/rails/test_unit/minitest_plugin.rb:9:in `aggregated_results': wrong number of arguments (1 for 0) (ArgumentError)
from /var/lib/gems/2.2.0/gems/minitest-5.10.2/lib/minitest.rb:597:in `report'
from /var/lib/gems/2.2.0/gems/minitest-reporters-1.1.9/lib/minitest/minitest_reporter_plugin.rb:26:in `each'
from /var/lib/gems/2.2.0/gems/minitest-reporters-1.1.9/lib/minitest/minitest_reporter_plugin.rb:26:in `report'

先のステップで導入予定のコードをtest/test_helper.rbに追記。

require "minitest/reporters"
Minitest::Reporters.use!

 

RailsTutorial に沿ってお勉強。(/var/lib/gems/2.3.0/gems/puma-3.4.0/lib/puma/binder.rb:255:in `initialize': getaddrinfo: Name or service not known (SocketError))

Railsチュートリアルに従って、何も考えずに手を動かしてたらエラーになったのでメモ。

Railsを起動して、ブラウザにUser画面を表示しようとしたら、Railsが落ちる。エラーメッセージは、こんなの。

/var/lib/gems/2.3.0/gems/puma-3.4.0/lib/puma/binder.rb:255:in `initialize': getaddrinfo: Name or service not known (SocketError)

StackOverflowで、同じのがあって、railsの起動の時に、定義してない変数でIP、ポートを起動しようとしているからとか。

stackoverflow.com

回答にある通り、IP、ポートを指定して起動すればOKでした。

rails server -b ${IP:-127.0.0.1} -p ${PORT:-3000}

 

Rails勉強しようと思ったらのっけからつまづいた。(Windows8.1でSQLite3のインストールができない)

Railsチュートリアルに従って勉強を始めたが、ネット環境が悪いためCloud9がちょっともっさりしてた。そこでローカルで環境を用意しようと思ったのがけちのつき始め。いくつかサイトを参考に、Railsのインストールまでは出来たが、SQLite3のmake&installがうまくいかない。

ネットでググると海外でもwindowsでやるのは厳しい、バージョン上がったら誰か凄腕プログラマーWindows用の対応するのを待つ羽目になるとか色々と書かれていたので、諦めてVMWareでやることにした。実際レスポンスが早いならOSはなんでも、、、。

UbuntuVMを用意して、以下のサイトに従ってインストールしたらサクッとプロジェクト作成、deployまでできた。

kwski.net

kwski.net

 

WindowsからはRubyごと削除。

d.hatena.ne.jp

heroween.hateblo.jp

Android Studioでサンプルアプリを作って、エミュレータで動作確認しようとしたらこんなエラーがでた。

f:id:name_untitled:20170518124733p:plain

Error:java.lang.RuntimeException: com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/LICENSE

ググったら、appのbuild.gradleにライセンス関係のファイルを除外する記述をするといいと書いてあった。

android {
    packagingOptions {
        exclude 'META-INF/DEPENDENCIES.txt'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/dependencies.txt'
        exclude 'META-INF/LGPL2.1'
    }
}

 

stackoverflow.com

 

 ライブラリのライセンス関係のファイルがかぶったりしてるのかなぁとおもっているけど、とりあえずは良しとしてまた確認する。

 

Messenger ChatBot をHerokuで作るメモ

byuzensen.com
qiita.com



package.json

{
  "name": "chatbotfblaojp",
  "version": "1.0.0",
  "description": "chatbot app for facebook messenger",
  "main": "index.js",
  "dependencies": {
    "body-parser": "^1.17.1",
    "crypt": "0.0.2",
    "ejs": "^2.5.6",
    "express": "^4.15.2",
    "request": "^2.81.0"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

index.js

const
  bodyParser = require('body-parser'),
  express = require('express'),
  crypto = require('crypto'),
  req = require('request');

var app = express();
app.set('port', process.env.NODE_PORT || 5000);
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.use(bodyParser.json({ verify: verifyRequestSignature }));

app.get('/webhook', function(req, res){
  if (req.query['hub.mode'] === 'subscribe' &&
      req.query['hub.verify_token'] === '') {
    console.log("Validating webhook");
    res.status(200).send(req.query['hub.challenge']);
  } else {
    console.error("Failed validation. Make sure the validation tokens match.");
    res.send(403);
  }
});

app.post('/webhook', function (req, res) {
  var data = req.body;

  // Make sure this is a page subscription
  console.log(data);
  if (data.object === 'page') {

    // Iterate over each entry - there may be multiple if batched
    data.entry.forEach(function(entry) {
      var pageID = entry.id;
      var timeOfEvent = entry.time;

      // Iterate over each messaging event
      entry.messaging.forEach(function(event) {
        if (event.message) {
          receivedMessage(event);
        } else {
          console.log("Webhook received unknown event: ", event);
        }
      });
    });

    // Assume all went well.
    //
    // You must send back a 200, within 20 seconds, to let us know
    // you've successfully received the callback. Otherwise, the request
    // will time out and we will keep trying to resend.
    res.sendStatus(200);
  }
});

function verifyRequestSignature(req, res, buf) {
  var signature = req.headers["x-hub-signature"];
  if (!signature) {
    console.error("Couldn't validate the signature.");
  } else {
    var elements = signature.split('=');
    var method = elements[0];
    var signatureHash = elements[1];

    var expectedHash = crypto.createHmac('sha1', '')
                        .update(buf)
                        .digest('hex');

    if (signatureHash != expectedHash) {
      throw new Error("Couldn't validate the 4 signature.");
    }
  }
}

function receivedMessage(event) {
  // Putting a stub for now, we'll expand it in the following steps
  console.log("Message data: ", event.message);
}

function receivedMessage(event) {
  var senderID = event.sender.id;
  var recipientID = event.recipient.id;
  var timeOfMessage = event.timestamp;
  var message = event.message;

  console.log("Received message for user %d and page %d at %d with message:",
    senderID, recipientID, timeOfMessage);
  console.log(JSON.stringify(message));

  var messageId = message.mid;

  var messageText = message.text;
  var messageAttachments = message.attachments;

  if (messageText) {

    // If we receive a text message, check to see if it matches a keyword
    // and send back the example. Otherwise, just echo the text we received.
    switch (messageText) {
      case 'generic':
        sendGenericMessage(senderID);
        break;

      default:
        sendTextMessage(senderID, messageText);
    }
  } else if (messageAttachments) {
    sendTextMessage(senderID, "Message with attachment received");
  }
}

function sendGenericMessage(recipientId, messageText) {
  // To be expanded in later sections
}

function sendTextMessage(recipientId, messageText) {
  var messageData = {
    recipient: {
      id: recipientId
    },
    message: {
      text: messageText
    }
  };

  callSendAPI(messageData);
}

function callSendAPI(messageData) {
  req({
    uri: 'https://graph.facebook.com/v2.6/me/messages',
    qs: { access_token: '' },
    method: 'POST',
    json: messageData

  }, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      var recipientId = body.recipient_id;
      var messageId = body.message_id;

      console.log("Successfully sent generic message with id %s to recipient %s",
        messageId, recipientId);
    } else {
      console.error("Unable to send message.");
      console.error(response);
      console.error(error);
    }
  });
}

var port = process.env.PORT || 5000;
app.listen(port, function() {
  console.log("Listening on " + port);
});

module.exports = app;

Windows 共有の詳細設定の情報をバッチで出力する。

ちょっと知り合いから質問されたので、調べた。

ネットワークの画面上で見えないPCがあるらしく、原因を調べたいとのこと。ぱっと思いついたのはコントロールパネル>ネットワークと共有センター>共有の詳細設定の設定がまずいのではということ。

これをいちいち確認するのではなく、バッチファイルで出せたらなぁと思って調べたらこんな記事がありました。

共有の詳細設定をプログラムから確認する方法

 

ネットワークの種類や規則名でも選んで出力が出来るみたい。

とりあえずこんな感じでバッチファイルを書きました。

netsh advfirewall firewall show rule all profile=private >> text.txt