読者です 読者をやめる 読者になる 読者になる

8t's BBR

よくつまったあれこれをメモ

久しぶりにphp扱ってみたら動作しない

web系 豆知識

 
以前phpで作成したアプリケーションを久しぶりにいじろうと思ったのですが、ブラウザにはコードが表示されたり、うまく動作しなかったりとで戸惑いました。


apache動いている?」
 -> http://localhost で確認。ちゃんと「It works!」と言ってくれる。


phpのバージョンあげたっけ?」
 -> terminalでphp -versionで確認。以前と同じで上がってない。


「あれ?なのにphpが動作しないの?」
 -> terminal で<?php phpinfo(); ?>と書いただけのphpファイル実行。うまくいく。


「え、ブラウザだけ駄目なん?」
 -> /etc/apache2/httpd.conf を確認したら、LoadModule php5_module libexec/apache2/libphp5.soコメントアウトされている。こいつか・・・



全然知りませんでしたがMacではOSアップデートの際に、/etc/apache2/httpd.confがデフォルトに書き換わるようですね。
そういえば以前OSアップデートしたなぁ・・・。

以前動いていたものが、久しぶりに触ると動かなくなっていて、びっくりしたお話でした。

Play Framework を使ってみた ③

web系

前記事:Play frameworkを使ってみた ② - 8t's BBR


前回からかなり時間が経ってしまいましたが、今回はPlayフレームワーク
データベースとEbeanを扱うにはどうするかについてまとめようかと思います。


※データベース初心者が送るデータベース初心者向けの説明になります。厳しい指摘は歓迎します。

※play2.5系のjavaの説明になるので、違うバージョンまたはscala使用者は公式などを参考にしてください。
Home - 2.5.x

データベースを扱うための設定

conf/application.conf

データベースの情報を記述します。単一のデータベースしか扱わないのであればデータソースの名前はdefaultのままで大丈夫です。
H2とかSQLiteとか色んなデータベースを扱うことができますが、今回はMySQLを例にとって説明していきます。

db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://localhost/playdb"
db.default.username=playdbuser
db.default.password="a strong password"

urlの最後は使用するデータベース名。usernameやpasswordは各自設定したものを。

build.sbt

以下の設定がなされていることを確認。なければ設定してください。

libraryDependencies += javaJdbc

また、使用するデータベースがH2以外のものであれば、以下の設定も必要です。
以下の例はMySQLの場合。最後の数字部分はバージョンですので適宜変更を。

libraryDependencies += "mysql" % "mysql-connector-java" % "5.1.36"

 

データベースへのアクセス

以下のようにするだけでデータベースを利用できます。

import javax.inject.Inject;
import play.mvc.*;
import play.db.*;

class Application extends Controller {

    private Database db;

    @Inject
    public Application(Database db) {
        this.db = db;
    }

}

クエリ実行

あまり推奨しませんが(理由は後述)、以下のようにすればクエリを実行できます。

import javax.inject.Inject;
import play.mvc.*;
import play.db.*;
import java.sql.*;

class Application extends Controller {

    private Database db;
    private Statement stmt;

    @Inject
    public Application(Database db) {
        this.db = db;
        Connection con = db.getConnection();
 
        try {
            stmt = con.createStatement();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public Result getMemberList() {
        String query = "SELECT * FROM MEMBER";
        ResultSet rs = stmt.executeQuery(query);
//             :          
        return ok();
    }

}

Ebeanの利用

先ほどクエリの実行の仕方を紹介しましたが推奨しませんと言いました。なぜなら、

  • クエリをコード中に書く必要がある
  • コードの記述量が多くなる

といったことによって、ミスをする可能性が高くなったり、読みづらくなったりと問題点があるからです。

では、どうすればいいのか。これをサポートする機能をPlayは提供してくれています。
具体的にはEbeanというものを利用することになります。
これ自体についてはまだ知ったばかりなので間違っているかもしれませんが、DB操作を楽にしてくれるものです。
たった一行でDB操作が可能になります。すごいですね。


では早速、設定ファイルをいじっていきます。

project/plugins.sbt

まずはこのファイルの最後に以下の設定を記述します。

addSbtPlugin("com.typesafe.sbt" % "sbt-play-ebean" % "3.0.0")

build.sbt

次に、PlayEbeanのプラグインを有効化します。おそらく最後のPlayEbeanの部分を追記するだけで大丈夫です。
PlayEbeanを認識してくれない場合がありますが、build.sbtをリフレッシュすれば直ります。(これに気づけず、すごい時間を浪費しました・・・)

lazy val root = (project in file(".")).enablePlugins(PlayJava, PlayEbean)

conf/application.conf

データソースの名前がdefaultのままであれば、以下の記述を追記してください。
違う場合はそれに合わせてdefault部分を変更してください。

ebean.default = "models.*"

この設定ではmodelsパッケージ以下を管理する形になりますが、お好きなパッケージを指定しても大丈夫です。



以上で準備完了です。


実際の利用例

まずは、データベースで管理するデータをクラスとして作成します。
ポイントはクラス宣言の前に@Entityアノテーションを付与することです。
これにより、データベースが管理するエンティティクラスとなります。


以下は適当に作成したMemberクラスです。

package models;

import java.util.*;
import javax.persistence.*;

import com.avaje.ebean.Model;
import play.data.format.*;
import play.data.validation.*;

@Entity
public class Member extends Model {

    @Id
    public Long id;

    @Constraints.Required
    public String name;

    public boolean isMale;

    public Long score;

    public static Finder<Long, Member> find = new Finder<Long,Member>(Member.class);
}
  • @Id : 登録時、主キーとなるIDを自動生成してくれるようになる。
  • @Constarints : 値の制限をかけることができる。Requiredの他にも色々ある。
  • Finder : 検索時に使います。おまじない的に書いてしまいましょう。

 


あとはMemberクラスのインスタンス(member)を生成すれば、

member.save();

で、データベースに登録できます。memberインスタンスのidは自動で生成されます。
idの値を保持しており、他の情報を変更したい場合は、

member.update();

とするだけです。


逆にデータベースからデータを引き出し、それを元にインスタンス生成することもできます。

Member member = Member.find.byId(id);

データを削除したい場合は、この後に

member.delete()

とするだけです。なんとわかりやすいことか。

トランザクション

データベースを扱うのであれば当然必要です。
メソッドに@Transactionalをつけるか、Ebean.beginTransaction()Ebean.commitTransaction()Ebean.endTransaction()を活用するかのどちらかで対応できます。

GeekToolでMacのデスクトップをかっこよく

豆知識 shell & command


Macのデスクトップをカッコ良くしたい。
以前からずっと考えてはいたが実行してなかったので、今回挑戦。

使用したのはGeekTool。

先に完成形を見せるとこんな感じです。
f:id:ykng0:20170131093103p:plain
まぁかっこよくなったかと言われれば人によりけりでしょうが、個人的にはそれっぽくなったので満足です。
あまりUnixコマンドに詳しくなくても、ネットの力を借りてなんとかここまでできました。


順に見ていこうと思いますが、参考にさせていただいた記事を先に紹介させていただこうと思います。
http://www.lifehacker.jp/2012/07/120727geektool.html
http://iici.cocolog-nifty.com/blog/2011/09/geektool-1b5c.html
http://gunbird.blog.fc2.com/blog-entry-1808.html
http://leopardgecko.hatenablog.com/entry/2016/10/25/161147


基本的なGeekToolの使い方

これは、こちらの記事を参考にしてください。
http://www.lifehacker.jp/2012/07/120727geektool.html

シェル系のgeekletならCommandRefresh everyFontsさえ指定するだけでも十分だと思います。
ちなみに、見た目が汚くてもフォント変えると整形されたりするので、色々試してお気に入りのフォントを探してみてください。
私は、ほぼ全てをCourierのボールドにしました。

以下が設定したコマンド一覧です。

 

基本情報

上から順に、OS、PCのモデル、CPU、メモリ情報です。

echo `sw_vers -productName` \(v`sw_vers -productVersion`\);
sysctl -n hw.model;
sysctl -n machdep.cpu.brand_string;
sysctl -n hw.memsize | awk '{print $0/1073741824" GB RAM"}';

 

システム情報

上から順に、CPUアイドル、メモリの空き、HDDの空いてる容量(あと、何パーセント使用されているか)、Uptimeです。
Uptimeは下のシェルスクリプトです。普通のuptimeコマンドもありますが、こっちの方がわかりやすい。丸パクリです。

top -l 2 | awk '/CPU usage/ && NR > 5 {print "CPU Idle: " $7}';
top -l 1 | awk '/PhysMem/ {print "RAM Free: " $6}';  
df -hl | grep 'disk1' | awk '{print "HDD Free: " $4" ( " $5 " used ) "}';

#!/bin/bash
then=$(sysctl kern.boottime | awk '{print $5}' | sed "s/,//")
now=$(date +%s)
diff=$(($now-$then))
days=$(($diff/86400));
diff=$(($diff-($days*86400)))
hours=$(($diff/3600))
diff=$(($diff-($hours*3600)))
minutes=$(($diff/60))
function format {
if [ $1 == 1 ]; then
echo $1 ' ' $2
else
echo $1 ' ' $2's'
fi
}
echo 'Uptime: '`format $days "d"` `format $hours "h"` `format $minutes "m"`

 

バッテリー情報

これはさっぱり解読不能でしたが、素晴らしい出来栄えだったので、即採用。

ioreg -l | grep -i capacity | tr '\n' ' | ' | awk '{print ("System Battery: ",$10/$5 * 100,"%")}';pmset -g batt |awk '{print $4 $5 $6}'|grep ';'|sed 's/;/ /g'; osascript -e 'set a to do shell script "ioreg -w0 -l | grep Capacity"' -e "set h to word 5 of a" -e "set z to word 33 of a" -e "set b to word 38 of a" -e "set c to 1000 * b / z" -e "set d to round c" -e "set f to d / 10" -e "set q to 1000 * h / b" -e "set w to round q" -e "set j to w / 10" -e '"Battery Health: " & j &"%"' | iconv -f utf-8 -t ucs-2-internal; ioreg -w0 -l | grep "Cycle Count" | awk 'BEGIN { FS = "=" } ; {print $8}' | awk 'BEGIN { FS = "}" } ; {print $1, "Cycles"}';

 

プロセス一覧(CPU利用率順)

稼働しているプロセスを、CPUをくっている順に表示します。
最後の数字を変えれば、表示数を変えることができます。

ps -arcwwwxo "command %cpu" | grep -v grep | head -13

 

プロセス一覧(メモリ利用率順)

稼働しているプロセスを、メモリをくっている順に表示します。
これも、最後の数字で表示数を変えることができます。

ps -amcwwwxo "command %mem" | grep -v grep | head -13

 

プロセス情報と平均ロード

上側がプロセス情報で、下が平均ロードプロセス数です。
プロセス情報は見た通りです。
平均ロードプロセス数については、左から順に1分、5分、15分単位です。
この数は1を切っている方がいいそうですが、基本1超えてる・・・
geekletの更新頻度が高いのが多すぎるせいかもしれません・・・

echo "Processes";
top -l 1 | awk '/Processes/ {print "total: " $2}';
top -l 1 | awk '/Processes/ {print "running: " $4}';
top -l 1 | awk '/Processes/ {print "sleeping: " $6}';
top -l 1 | awk '/Processes/ {print "threads: " $8}';

echo;
echo "Load Avg";
top -l 2 | awk '/Load Avg/ && NR > 5 {print $3 " " $4 " " $5}';

 

ネットワーク状況

接続しているネットワークの情報を教えてくれます。
繋がってないならOFFLINEとか書いてくれるし、かなりスマート。
時々、Script time outとなるのが非常に残念。なんとかできないものか・・・。
あと、MacBook Airの場合は有線LANが無いのでe0がWi-Fiだが、有線LAN付属モデルの場合はe0が有線、e1がWiFiとなるのでスクリプトを修正する必要があるそうなので、ご注意を。

#!/usr/bin/perl

$en0_info = `ifconfig en0 | grep "inet" | grep -v 127.0.0.1`;
$en1_info = `ifconfig en1 | grep "inet" | grep -v 127.0.0.1`;
$ext_info = `curl --silent http://checkip.dyndns.org | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}'`;
$wifi_network = `/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | awk -F: '/ SSID: / {print $2}' | sed -e 's/.*SSID: //'`;
$wifi_txRate = `/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | awk -F: '/ lastTxRate: / {print $2}' | sed -e 's/.*lastTxRate: //'`;
$wifi_maxRate = `/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | awk -F: '/ maxRate: / {print $2}' | sed -e 's/.*maxRate: //'`;
$wifi_channel = `/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | awk -F: '/ channel: / {print $2}' | sed -e 's/.*channel: //' -e 's/,1//'`;
if($ext_info) {
 $output .= "External: $ext_info";
} else {
 $output .= "External: OFFLINE \n";
}
if($en0_info) {
 $en0_info =~ /inet (.*) netmask/s;
 $en0_info = $1;
 $output .= "Wi-Fi: $en0_info \n";
 $output .= "  SSID: $wifi_network";
 $output .= "  Channel: $wifi_channel";
 $output .= "  Transmit Rate: $wifi_txRate";
 $output .= "  Max Rate: $wifi_maxRate";
} else {
 $output .= "Wi-Fi: INACTIVE \n";
}
if($en1_info) {
 $en1_info =~ /inet (.*) netmask/s;
 $output .= "Ethernet: $1 \n";
} else {
 $output .= "Ethernet: INACTIVE \n";
}
print "$output";

 

天気

これが一番大変だった。
基本的にYahoo天気などを利用するものだが、昔の記事のやつだと、APIの仕様が今と違うようで、そのままコードを使えない。
かといって、どこを変えればいいかもわからない・・・
そのため、新しめの記事のものを採用させていただきました。
説明は全て丁寧に書かれてあるので記事の紹介だけにします。
http://leopardgecko.hatenablog.com/entry/2016/10/25/161147

 

日付と時刻

この部分は一番アレンジしがいのある部分になるかと思います。
基本的に一つのgeekletにつき一つしかフォントや大きさを指定できないので、別々に作って組み合わせていくのがオシャレにできるポイントかなと思います。

また、この類のgeekletはたくさん作られているので、以下などから探すのもオススメです。
http://www.macosxtips.co.uk/geeklets/alltime/page/1

私が採用したシンプルなやつはこちらになります。上が日付で、下が時間です。
曜日を英語表記にしたい方は、下の方にあるset locale environmentにチェックを入れてください。

date "+%m.%d (%a)"
date "+%H:%M"

 

カレンダー

フォントによっては結構ぐちゃぐちゃの形になってしまうので、綺麗に整形されるものを選択する必要があるかと思います。
ちなみに私が使用したのは上にも書きましたが、Courierのボールドです。
私の設定では、今日の日付は色付けしてくれます。途中の31の数字をいじれば他の色にできたりします。

cal_head=`cal | head -1`; cal_tail=`cal | tail -7`; today=`date "+%e"`; echo "$cal_head"; echo "${cal_tail/${today}/\033[1;31m${today}\033[0m}";

 

最後に

自分なりの画面が完成した時の達成感は半端なく、感動的でしたが、なんだかんだシンプルな画面もそれはそれでかっこいいので、気分によって変えたりできればと思います(笑)

Play frameworkを使ってみた ②

web系

前記事:Play frameworkを使ってみた ① - 8t's BBR


前記事に続き、今回はPlayフレームワークでのアプリケーションの開発に最低限必要な部分をまとめたいと思います。

基本的には公式のDocumentationに沿って翻訳しただけになります。


あくまで最低限の部分のみを説明するので、他の実装方法などより詳しい情報は公式を確認してください。

[公式ドキュメント] Home - 2.5.x
[日本語版(但し2.4まで)] Home - 2.4.x


Action

まず、Actionについての説明から。

ざっくり言うと「Play アプリケーションが受け取ったリクエストを処理し、クライアントへ送るレスポンスを生成する Java のメソッド」です。

以下はその一番簡単な例です。

public Result index() {
    return ok("Got request " + request() + "!");
}
  • Result:クライアントへ送るレスポンス。play.mvc.Result型。
  • ok()HTTPステータスコード200(OK)のレスポンスを返す。
  • request():受け取ったリクエストを呼び出す

以上のことから、このJavaメソッドは「受け取ったリクエスト内容をステータスコード200でレスポンスしている」ことがわかると思います。

この3点が基本です。


Controller

ではここで、
「ActionとかいうJavaメソッドはわかったけど、どのクラスに書けばええねん。なんでもええんか?」
という疑問が出てきます。答えはNOです。

名前は自由ですが、play.mvc.Controller型を継承しているクラスでないといけません。
でも逆に言えばこれだけです。

package controllers;

import play.*;
import play.mvc.*;

public class SimpleApplication extends Controller {

    public Result index() {
        return ok("It works!");
    }

}

言ってしまえば、これだけでアプリケーションの動作の記述はほぼ完成してしまいます。
まぁこのままでは、何のロジックも持たず、ただ「It works!」としか言わないクソみたいなアプリケーションですが(笑)


HTTPルーティング

先ほどクソみたいなアプリケーションを作りましたが、次は「どうリクエストしたら「It works!」って言うねん」ってなりますね。
これはconf/routesに書いていきましょう。

GET  /     controllers.SimpleApplication.index()

はい、これだけです。

先頭から順に

  • HTTPメソッド
  • URL
  • アクション呼び出し先

になります。


HTTPメソッド

これは言うまでもないかもしれませんが、
GET、PATCH、POST、PUT、DELETE、HEAD
です。お好きなものを指定できます。

URL

URLの指定方法はいくつかあります。

静的

リクエストを例えばGET/clients/all に完全一致させたいときは、次のように定義できます。

GET  /clients/all     controllers.Clients.list()             

これが基本ですかね。

動的

リクエストの際に、URL からパラメータ(例えば、クライアント ID) を取得するような場合には、動的パートを追加する必要があります。

GET  /clients/:id     controllers.Clients.show(id: Long)

渡したいパラメータ部分の前に:をつける感じですね。
また、呼び出し先にも引数を指定しますが、例のようにパラメータ名: 型という記述の仕方であることに注意してください。

その他

複数の/をまたぐ動的パートや、動的パートで独自の正規表現を使うなど
他にもありますが、その辺は公式ドキュメントを参考にしてください。
https://www.playframework.com/documentation/ja/2.4.x/JavaRouting




これらだけでは、今時のWEBアプリケーションとまでは全然いきません。
ですが、最低限これだけ押さえておけばとりあえずPlayでアプリケーションを作れます。





次回は、「playでデータベースを使うには」でいきたい。

Play frameworkを使ってみた ①

web系

遅くなったが新年初エントリー。就活で書く暇がなかった。


という訳で、今回はPlayというフレームワークを使ってみました。
軽く調べてみると以前使ったことのあるSpringの次くらいにトレンドな感じの印象。


使ってみた感想として、確かに慣れれば開発がはかどりそうだが、やはり初心者が触り始めるには難しい点があります。

  • Documentationが英語
  • Documentationに書かれていることがすべて正しいとは限らない
  • うまくいかない時の対処法はググるしかない

これらは割と何に対しても言えることかもしれないが、特に2番目の問題はきつい。
情報自体が間違っているという訳ではないです。
ただ昔のバージョンでの書き方のまま更新されておらず、いざ真似すると非推奨と怒られたり、うまく動作しなかったりでもう・・・。



そこで今回は複数回にわたって、Playフレームワークの使い方を簡単に紹介します。

第1回ではIntellijで開発を始めるまでを説明しようかなと思います。

ダウンロード

まずはダウンロードから。以下のページからできます。
https://www.playframework.com/download

いろいろとダウンロードできるものがありますが、とりあえずPlayフレームワークを使ってみたいという人は画面中腹あたりのPlay with Activatorという項目のActivator 1.3.12 including Play 2.5.12というものを選択してください。ダウンロードが始まります。

f:id:ykng0:20170123222435p:plain


これを動かすにはJDK8が必要だが、Playフレームワークを使おうと思っている方ならまず入っていると思います。

「え・・・・」って方は以下で今すぐJavaをインストールしておきましょう。PATHに追加しておくのも忘れずに。
Java SE Development Kit 8 - Downloads
Javaのインストール方法、およびPATHへの追加の仕方は調べればいくらでも出てきます。


ダウンロード以降はこちらが非常に参考になります。
Installing - 2.4.x

クイックスタートの項目の最初に最新の Typesafe Activator を ダウンロードする とありますが、これは先ほどダウンロードしたActivatorなので気にしない。
あとは手順通りにやれば、とりあえずうまくいくはず・・。

activatorコマンドがないという方はbinディレクトリにあるはずなのでそれを指定してください。
また、そこにPATHを通しておくと便利です。


Playのプロジェクト作成法

Playのプロジェクトの作り方は細かく説明すると大変なので、とりあえず簡単な作り方を。

まずはプロジェクトを作りたいディレクトリまで移動してから、以下のコマンドを順に実行します。

// [project-name]にはお好きなプロジェクト名を指定してください。
$ activator new [project-name] play-java
$ cd [project-name]
$ activator run

プロジェクトをactivator newで生成後、activator runせずにIntellijにインポートしてからRunしようとすると
view.htmlなどのシンボルが見つかりませんとのエラーが出ることがあります。
ので、こうなってもなってなくても3の手順は一回踏むべきかもしれない。(その後に Ctrl + D で終了しても大丈夫)
ちなみに、javaじゃなくてscalaで開発したいって方は、最初のnewでplay−javaではなくてplay-scalaと指定してください。


Intellijへのインポート手順

Playのアプリケーションはeclipseなどでも開発できますが、この記事ではIntellijでのインポート手順を説明します。

Intellij派の人もそうでない派の人もこちらを参考に進めてください。
https://www.playframework.com/documentation/ja/2.4.x/IDE


Intellijで展開するにあたって、注意しなければいけないのが、先ほどのページにも書かれているが、Play2.4からはNew Projectから作成のは非推奨であるという部分。
これは先ほどのactivator newからプロジェクトを作成する方法をせずに、Intellijで直接作成するというなんとも便利そうな話であるが、少なくとも2.5の私の環境では途中で失敗してできなかった。非推奨ではなくて、やめてくださいと書いてほしい。
大人しく、activator newからプロジェクトを作成してそれをIntellijにインポートするようにしましょう。


では、前置きが長くなりましたが、以下がIntellijへのインポート手順になります。

  1. Intellijのメイン画面で Import Projectを選択し、先ほど作成したプロジェクトを選択。
  2. Import project from external modelからSBTを選択。Nextを選択し、次もJDKが正しく設定されているのを確認したらFinishを選択。
  3. プロジェクトを展開できたら、Project Structure を開き、 Modulesの項目からroot の Dependencies の項目に scalasdk があることを確認。なければ追加。

f:id:ykng0:20170123230757p:plain

最後にRun Configurationの設定も行いましょう。+をクリックして SBT Tasks を選択。Tasks に run とだけ書いて apply して保存。これで Control + r で実行できます。

実行したらhttp://localhost:9000でアクセスして、動いていることを確認できます。


うまくいかない時

Intellijにインポートする時に、Import project from external modelからSBTを選択しようにも項目が出てこない場合があります。
これを解決するには、Intellijscalaプラグインをインストールする必要があります。
Intellijのメイン画面から、Configure->Pluginsを選択し、Install JetBrains plugins...を選択。
そしてscalaと検索し、出てきたプラグインをインストールすれば問題は解決されると思います。
f:id:ykng0:20170123231726p:plain
f:id:ykng0:20170123232030p:plain
f:id:ykng0:20170123232202p:plain





次回は、Playを使ったアプリケーション開発をする上で最低限必要なポイントを紹介したいと思います。
Play frameworkを使ってみた ② - 8t's BBR

Slackのボットのアイコン画像の指定

豆知識

こんばんは、世間はクリスマスで賑わっていますが、僕はいつもと変わらぬ1日でした。
いえ、ボッチではありません。Slack Incoming Webhooks を利用してBotと遊んでいましたよ。

さて、ヤジが飛んでくる前に本題に入ります。
先ほど紹介したSlackのBotですが、いろいろ凝りだすと、やはりアイコンにもこだわりたくなるものです。

普通はBotの設定ページにて、[Upload an Image]か[Choose an emoji]から選択するだけで済みます。
f:id:ykng0:20161225222952p:plain


・・が、僕のようなひねくれ者は、JSONBotのパラメータを設定しているのでJSONをいじって変更したい。
そんな時は、icon_urlicon_emojiで指定します。

          :
    'icon_url' : 'http://path/to/image',
    'icon_emoji' : ':ghost:',
          :

みたいな感じです。ちなみに、このicon_emojiの例は名前どおりゴーストです。結構かわいい感じ。
絵文字チートシートEmoji cheat sheet for GitHub, Basecamp and other services

2つとも指定した場合は、icon_emojiの方が優先されます。


困ったことに、icon_urlはあくまでHTTPアクセスできるもの限るっぽいです。
ローカルにある画像を指定したいのですが、どこかにアップロードしてそのURLを指定するしかなさそうです。

ローカルにあるものを直接指定できる方法をご存知の方はどうかご一報ください。

CDHをアンインストールせずに、別のHadoopを使いたい

Hadoop

以前の記事でも話したが、研究室のサーバーを借りてHadoopクラスタを組みなおした。
ようやくセッティング終わったーとか喜んだのもつかの間、確認のために

$ hadoop version

とやってみると、設定しているHadoopのバージョンと違う・・・


どうやら以前Hadoopを研究で扱っていた先輩のCDHが残っているようでした。


CDHでは、/usr/bin以下にHadoopの各種コマンドが設定されるので、こちらを参照してしまっています。

昔の記事
Hadoopクラスタ構築への道 ~疑似分散編~ - 8t's BBR
では、/etc/profile

export PATH=$PATH:$HADOOP_HOME/bin

を設定していましたが、exportする前の$PATHには/usr/binのパスがあるので、読み込まれる順番的にCDHの方が優先されており、せっかくのパスの設定が全く意味を成してない。


やはりCDHは嫌いだとぼやきながらCDHをアンインストールする方法をググり、めんどくさいことがわかって絶望したところで教授から一言
「$PATHの前にexportすれば?」


その通りすぎました。

早速、

export PATH=$HADOOP_HOME/bin:$PATH

と変更して無事解決。


これで最早レガシーとなったCDHと自分で設定したHadoopを共存させることができました。


別にHadoopだからっていう話ではない上、言われてみれば相当しょーもない話ですが、言われるまで全く気づかなかった反省を込めて負の遺産を残します。