TRY AND ERROR

気になったこと、勉強したこと、その他雑記など色々メモしていきます。。Sometimes these posts will be written in English.,

PythonのAnacondaってどうなん??

気軽にscrap and buildできるPython3の汎用開発環境を作りたいと思ってDockerfileを書いてみました。

dockerfile-for-python-proto/Dockerfile at master · kentaro-a/dockerfile-for-python-proto · GitHub


Pythonあまり触ったことないのでモジュルやら何やら詳しくないのですが、
Python-3.5.1をソースからインストールしてpip,pandasその他を入れるみたいなことをやってる。。


Tensorflow触ってみたいので↑から作ったコンテナでインストールしようとしたものの、
依存モジュール絡みでもんのすごく面倒くさいっぽい。

いろいろ調べていくうちにAnacondaというプラットフォームを発見。
どうやら分析寄りの環境を簡単に構築できるらしい、、、というかPythonの環境管理全般いけるみたい。

pipであくせくするよりもこれで管理したほうがいいんじゃね?と思ったんですが、どうなんでしょうか。。

まあとにかくAnaconda試してみようと思います。

WordPressのAMPプラグインで/ampが真っ白になった件

WordPressのAMPプラグインを入れると一発でAMP化できるらしい、
という噂を聞いて早速試す、、、無事撃沈。
若干ハマったのでメモします。

・使ったプラグイン
AMP — WordPress Plugins


こちらのブログを参考にしたのですが、自分の環境でうまくいきませんでした。
プラグイン公式サイトのFAQに同じ質問が挙がっていたものの、未解決でした。。
WordPressのプラグインでブログをAMP対応にしてみた | 海外SEO情報ブログ



あれこれ調べた結果、サーバにphp-xmlがインストールされていなかったため、
プラグインのモジュール内でDomDocumentクラスが使えずに落ちていたことが原因でした。

WordpressのconfigでdebugモードをONにしてエラーを出してみると、
DomDocumentクラスが使えないみたいなメッセージがしっかりと出てました。

php-xmlをインストールしてapache再起動で解決。

yum -y install php-xml
service httpd restart


ちなみに、AMPプラグインでは現状投稿ページしかAMP対応できないそうです。
AMPのバリデートエラーもブラウザの機能でチェックできるようです。
詳しくはこちらで紹介されています。
検証!AMPに沿ったマークアップとエラーチェックの方法をご紹介! | サクラサクLABO公式ブログ



ヤレヤレ。。

mysqlでtinyintがbooleanになる件

mysqlでtinyint(1)を指定したカラムのデータをcakephp3のモジュールで取得した際に、booleanとして扱われて困った。。

mysqlのバージョンは5.6.27

cakeのバグか?とも思ったんですが、リファレンスを見てみるとちゃんと書いてあった!

・BOOL、BOOLEAN
These types are synonyms for TINYINT(1). A value of zero is considered false. Nonzero values are considered true:

MySQL :: MySQL 5.6 Reference Manual :: 11.1.1 Numeric Type Overview

mysqlではbooleanはtinyint(1)のシノニムであり、0はfalse、0以外はtrueとして評価するとのことなので、cakeはtinyint(1)の値をbooleanに変換して処理してしまうようです。
ただ、実際にtinyint(1)には-128~127の整数値を入れられるので、ハマってしまう人も多いのではないでしょうか。

PHP7三項式まわりが快適すぎる

PHP7の三項演算あたりを本格的に使ってみましたが、快適すぎてやばいです!

あるkeyが存在するかどうかわからない配列をマージするような場合、
いちいちisset()しなくてよくなった!!

array_merge(
    $a['key'] ?? [],
    $b['key'] ?? [],
    $c['key'] ?? [],
    $d['key'] ?? []
);


isset地獄にみなさん1度はハマったことがあると思いますが、
PHP7だとスッキリしますね。

【Ruby】ChatworkAPI for Ruby

前回、ChatworkAPIクラスのPHP版を公開しましたが、今回Ruby版も作りました。

class Chatwork

	# イニシャライズ
	# apiToken: 自身のAPIトークン
	def initialize(apiToken)
		tokenHeaderKey = "X-ChatWorkToken: "
		@apiToken = apiToken										# APIトークン
		@reqHeader = "X-ChatWorkToken: #{@apiToken}"				# リクエストヘッダ
		@room = getRooms();        									# ルームID
	end


	# ルーム一覧取得
	def getRooms()
		ret = {}
		uri = URI.parse("https://api.chatwork.com/v1/rooms");
		
		# httpクラス
		http = Net::HTTP.new(uri.host, uri.port)
		http.use_ssl = true
		http.verify_mode = OpenSSL::SSL::VERIFY_NONE
		
		# httpリクエスト情報オブジェクト
		request = Net::HTTP::Get.new(uri.request_uri)
		request.add_field("X-ChatWorkToken", @apiToken)
		
		# httpレスポンス
		response = http.request(request)

		# ルーム名:ルームIDのハッシュにする
		JSON.parse(response.body).each{|data|
			ret[data["name"]] = data["room_id"]
		}
		return ret

	end
	private:getRooms


	# ルーム名からルームIDを取得する
	# roomName: ルーム名
	def getRoomID(roomName)
		return @room[roomName]
	end


	# メッセージを送る
	# roomid: ルームID
	# msg: メッセージ
	def sendMessage(roomid, msg)
		uri = URI.parse("https://api.chatwork.com/v1/rooms/#{roomid}/messages");

		# httpクラス
		http = Net::HTTP.new(uri.host, uri.port)
		http.use_ssl = true
		http.verify_mode = OpenSSL::SSL::VERIFY_NONE

		# httpリクエスト情報オブジェクト
		request = Net::HTTP::Post.new(uri.request_uri)
		request.set_form_data({'body'=>msg})
		request.add_field("X-ChatWorkToken", @apiToken)
		
		# ChatworkAPIにpostする
		http.request(request)
	end

end


使い方も前回同様にAPIトークンを渡してnewし、getRoomIDにメッセージを送信したいルーム名を渡してルームIDを取得、
sendMessageでメッセージを送るといった流れです。

GitHubリポジトリこちら


最低限の機能しか実装してませんのでカスタマイズしてみてくださいm(_ _)m

【PHP】ChatworkのAPI使ってみた

チャットワーク(Chatwork)のAPIを使って指定ルームにメッセージを送る
PHPのクラスを作ってみました。

バッチ処理の結果をチャットワークで見たい、メールの設定がめんどくさい、
みたいなときに使えるかも。。


クラスファイル:Chatwork.php

<?php

class Chatwork {
	
	private $tokenHeaderKey = "X-ChatWorkToken: ";
	private $apiToken;		//APIトークン
	private $reqHeader;		//リクエストヘッダ
	private $room = [];		//ルームID

	/*
	 * コンストラクタ
	 * $apiToken: 自分のAPIトークン
	*/
	public function __construct($apiToken) {
		$this->apiToken = $apiToken;
		$this->reqHeader = ["{$this->tokenHeaderKey}{$this->apiToken}"];
		$this->getRooms();
	}
	
	/*
	 * ルーム一覧を取得
	 * $apiToken: 自分が所属する部屋の一覧を取得
	*/
	private function getRooms() {
		$uri = "https://api.chatwork.com/v1/rooms";
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $uri);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $this->reqHeader);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		$ret = json_decode(curl_exec($ch));
		curl_close($ch);

		foreach ($ret as $r) {
			$this->room[$r->name] = $r->room_id;
		}
	}
	
	/*
	 * ルームIDを取得
	 * $roomName: ルーム名
	 * return: ルームID、見つからない場合false
	*/
	public function getRoomID($roomName) {
		return isset($this->room[$roomName]) ? $this->room[$roomName] : false;
	}
	
	
	/*
	 * ルームIDを指定してメッセージを送る
	 * $roomid: ルームID
	 * $msg: 送信メッセージ(改行は\n)
	*/
	public function sendMessage($roomid, $msg) {
		// リクエストURI
		$uri = "https://api.chatwork.com/v1/rooms/{$roomid}/messages";

		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $uri);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $this->reqHeader);
		curl_setopt($ch, CURLOPT_POST, true);
		curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['body' => $msg]));
		curl_exec($ch);
		curl_close($ch);
	}

}

Chatwork.phpをinclude。自分のAPIトークンをコンストラクタに渡してインスタンス化すればOK。

$cw = new Chatwork('[API token]');


メッセージを送りたい部屋のルームIDを指定してメッセージを送れます。

$cw->sendMessage("[roomID]", "[Message]");

部屋名からルームIDを取得することもできます。
(というかChatwork画面から各部屋のルームIDを知る方法がわからなかった。。)

$roomid = $cw->getRoomID('[Room name]');

ほんと最低限の実相しかしてないので、興味ある方は公式ドキュメントを
参考に実装してみてはいかがでしょうかd( ̄  ̄)


Git:
https://github.com/kentaro-a/use-chatwork-api

参考:チャットワークAPIドキュメント

【PHP】巨大ファイルを読み込むとき

PHPでサイズの大きいファイルを読み込む時のメモ。


外部ファイルを全部読み込めればOK、ただし読み込めなかった場合には
エラーを返すというロジックを組みたかった。


たとえば、外部サイトをスクレイピングする際に、
HTMLファイルサイズが一定サイズを超える場合は取得しないよー、みたいなことです。
(もちろん法的に問題ない範囲での話ですが。。。)


file_get_contentsではオプションで読み込むバイト数を指定することはできますが、
この場合途中までの不完全なファイルになってしまう。


なので、1KBずつ読んで指定サイズを超えるた場合にエラー、
最後まで読みきれた場合はそのコンテンツを返す関数をつくってみた。

function ex_file_get_contents($uri, $maxSize) {
    $data = '';
    $size = 0;
    $K = 1024; //バイト計算上の1KB(≒10^3)
    $fp = @fopen($uri, "r");
    if ($fp) {
        while (!feof($fp)) {
            if ($size > $maxSize) {
				// 最大サイズを超えた時点で処理終了
            	@fclose($fp);
            	return false;
         	}
         	$data .= @fread($fp, $K);
         	$size += $K;
        }
        @fclose($fp);
    } else {
        return false;
    }
    return $data;
}