Excelで佐々木希を描く with Scala

これのあれです。
qiita.com

概要

これの他言語portとしてScala版をつくってみました。(もう本家投稿から2ヶ月も経ってた…
qiita.com
ScalaなのでExcelJavaライブラリであるApache POIを使って、セルの色塗りをしました。

環境

コード

import java.io._
import java.awt.Color

import org.apache.poi.xssf.usermodel.{XSSFColor, XSSFWorkbook}
import javax.imageio.ImageIO

import org.apache.poi.ss.usermodel.CellStyle

object main {
  val PixelHeight:Short = 35
  val PixelWidth:Short = 50
  val FilePrefix:String = "sasaki_nozomi"
  val XlsxPath:String = ".\\" + FilePrefix + "_scala.xlsx"
  val ImagePath:String = ".\\" + FilePrefix + ".jpg"

  def main(args: Array[String]): Unit = {
    val image = ImageIO.read(new File(ImagePath))
    val workbook = new XSSFWorkbook()
    workbook.createSheet(FilePrefix)
    val sheet = workbook.getSheetAt(0)
    val width = image.getWidth()
    val height = image.getHeight()
    for( j <- 0 until height ) {
      sheet.createRow(j)
      val row = sheet.getRow(j)
      row.setHeight(PixelHeight)
      for( i <- 0 until width ) {
        row.createCell(i)
        val cel = row.getCell(i)
        val pixel = image.getRGB(i, j)
        val color = new XSSFColor(this.getRGBArray(pixel))
        val style = workbook.createCellStyle()
        style.setFillPattern(CellStyle.SOLID_FOREGROUND)
        style.setFillForegroundColor(color)
        cel.setCellStyle(style)
      }
    }
    for( i <- 0 until width ) {
      sheet.setColumnWidth(i, PixelWidth)
    }

    val outfile = new java.io.FileOutputStream(XlsxPath)
    workbook.write(outfile)
    outfile.close()
  }
  def getRGBArray(pixel:Int):Color = {
    val r:Int = (pixel >> 16) & 0xff
    val g:Int = (pixel >> 8) & 0xff
    val b:Int = pixel & 0xff
    new Color(r,g,b)
  }
}

結果

f:id:bhind:20160810154925p:plain

ハマったこと・課題など

  • ハマった: IntelliJgithubへのリモートリポジトリの作成からpushまでが新規でできない(いまもできない)
  • ハマった: XSSFColorがRGBのbyte arrayコンストラクタを最初使ってたのだが、byteのMAX_VALUEって127やん?255入らんやん?負数つかうん?と思ってやめた(別のコンストラクタにした)
  • ハマった: セルの背景ぬるんだろとStyle::setFillBackgroundColorをよびつづけてた(正解はsetFillForegroundColorおよびパターン指定)
  • 課題: 行がすすむにつれて処理がすっごく重くなる。(小一時間以上かかる)メモリ上のXSSFWorkbookがボトルネックかと思い、20行ずつファイルに書き出してみるも結局速度変わらず。XSSWorkbookインスタンス構築でもうがっつりメモリに乗せちゃってるんだろうなと想像。
  • 良かったこと: IntelliJ買ってよかった(Eclipseのころより楽な気がした。まあ最近ずっとPhpStorm使ってたってのもあるけど)

google chrome でダウンロードすると勝手にファイルが実行されるのを無効化した

Windows 10Mac OS X El Capitanの両方で突然Excelファイルをダウンロードすると実行されるようになりました。
ダウンロード時に両方にチェックをいれてしまって、chromeユーザー設定で同期されてしまったのかな。。。
なので解除方法の備忘録。

  • 右上のメニューボタン(三みたいなの)をおしてメニューの[設定]をクリック
  • 左ペインの同じく[設定]をクリック
  • 右ペインをスクロールして[詳細設定を表示...]をクリック
  • [ダウンロード]の項目にあるボタン[ファイルを自動的に開かないようにする]をクリック

これで解除できた。。けどWindowsOS Xでそれぞれしないとダメだった(´・ω・`)

local で npm インストールした library が heroku で deployしたら Can not findになった時の対処法

自分用備忘録です。
local で npm インストールした library が heroku で deployしたら

ERROR Error loading scripts from npm package - Error: Cannot find module '[module_name]'

とかエラーになった場合の対処法です。

local で

npm install --save [module_name]

して再push。github URL直指定のとか、コード内でrequireしたlibraryで発生しました。

hubot-slack v4 (というかSlack SDK RTMClinet)の channel 指定方法が変わっててハマった件

まあ、ほぼほぼT/Oですけど。お急ぎの方のために結論だけ先に書きます。
short answer:
いままでの"#general"の代わりにhttps://api.slack.com/methods/channels.list/testで取得できるjsonのCで始まるidを指定する


最近、メール監視で取りこぼしがあって「メールなんてみないでござる。Slackがいいでござる。」と進言したところ提案が通ったのでhubotなどでその恩恵を拡大しようと思い、アピールのためゲリラ豪雨対策として下記のhubotを入れようと試みたのが2日前なのです。
qiita.com
hubot自体はどこにいれようかなーと迷ったのですが、開発用のAWSよりherokuにしようということでherokuに新しいアプリを作りデプロイしました。
qiita.com

HUBOT_RAINFALL_ALERT_CHANNELにはありがちな"general"とかのディスプレイネームを指定してました(フラグ)。
rainfallコマンドは通ったのですが、rainfallcheckコマンドがheroku logs -t(プロジェクトディレクトリで)を監視すると下記のエラーにより止まってしまいました。

Unhandled rejection SlackRTMError: invalid channel id

これについて自分で他のサンプルをつくるなど1.5日程度悩んだ結果、Slack SDK RTMClientのドキュメントから
Real Time Messaging API | Slack

You can send a message to a private group or direct message channel in the same way, but using a Group ID (C024BE91L) or DM channel ID (D024BE91L).

package.json:
( ^ω^) ⊃"hubot-slack": "^4.0.2",
⊂( ^ω^) ≡⊃⊂≡ ( ^ω^) ⊃
( ^ω^) ⊃"hubot-slack": "^3.4.2",

これでも動くけど!大人になって。
qiita.com
あとはshort answerをごらんください。

さて、herokuでnode cronが動かないんですけど…

nagios と slack を Amazon Linux から連携しようとしたら エラー で半日程度かかった件

slackにはnagios integrationがあるから楽勝と思ってたんですが、今日半日かかったのでメモ。

  • PCから対象チームのSlack Web UIにログインし、左上チーム名をクリックしたメニューから[App & Integrations]を選択します。この辺りのワーディングが結構時間とともに変わるので最初場所がわからんかった。
  • Find new apps ... のinput formからnagiosで検索します。
  • 左の[Add configuration]をクリックします。あとは、基本[Setup Instructions]の通りなのですが。。。
  • Amazon Linuxにはaptなんてないのでyumで必要なperlライブラリをインストールします。こう。

yum info perl-libwww-perl perl-Crypt-SSLeay

  • Download the plugin and move it into place:(Slackのまんまです)

wget https://raw.github.com/tinyspeck/services-examples/master/nagios.pl
cp nagios.pl /usr/local/bin/slack_nagios.pl
chmod 755 /usr/local/bin/slack_nagios.pl

  • Edit the slack_nagios.pl, find the $opt_domain and $opt_token variables, and set them to:(Slackのではちゃんとあなたの環境のが書かれているのでコピペして貼ればよいです)

my $opt_domain = "hogehugapiyobaaaaan.slack.com"; # Your team's domain
my $opt_token = "SQUIGGLEWHATEVERTHINGS"; # The token from your Nagios services page

  • ここでinstructionsにはないのですが試し打ちしてみます。#channelnameはご自身のチャンネル名にあわせてください(なければ作ってください。たぶんprivateで)

/usr/local/bin/slack_nagios.pl -field slack_channel=#channelname -field HOSTALIAS="HOSTNAME" -field SERVICEDESC="SERVICEDESC" -field SERVICESTATE="SERVICESTATE" -field SERVICEOUTPUT="SERVICEOUTPUT" -field NOTIFICATIONTYPE="NOTIFICATIONTYPE"

  • だがしかしエラーが。こんなの。

501 Protocol scheme 'https' is not supported (LWP::Protocol::https not installed ...

yum install perl-Net-SSLeay
yum install perl-Crypt-SSLeay
yum install perl-IO-Socket-SSL

  • が、ダメ。なので同じページにあるcpanminusでLWP::Protocol::httpsをインストールしようとするも、cpanmがそもそもありませんでした。
  • cpanmのインストール。このページのとおりこう。

curl -L http://cpanmin.us | perl - --sudo App::cpanminus

  • が、エラー。こんなん。

Can't locate ExtUtils/Manifest.pm

  • perl-ExtUtils-Manifest をインストール。

このページを参考にこう。

sudo yum install perl-ExtUtils-Manifest

  • やっとLWP::Protocol::httpsをインストール

sudo cpanm LWP::Protocol::https

  • slack_nagios.plを試し打ち。

これでOkayならあとはnagiosの設定。というかinstructionsまんま。etc/objects/contacts.cfgに配信したいユーザー定義と配信コマンド名、そのコマンド名の定義をetc/objects/commands.cfgに記載して終了。

define contact {
contact_name slack
alias Slack
service_notification_period 24x7
host_notification_period 24x7
service_notification_options w,u,c,r
host_notification_options d,r
service_notification_commands notify-service-by-slack
host_notification_commands notify-host-by-slack
}
...
define contactgroup {
contactgroup_name admins
alias Nagios Administrators
members root,slack
} # 既存グループにメンバー追加

define command {
command_name notify-service-by-slack
command_line /usr/local/bin/slack_nagios.pl -field slack_channel=#channelname -field HOSTALIAS="$HOSTNAME$" -field SERVICEDESC="$SERVICEDESC$" -field SERVICESTATE="$SERVICESTATE$" -field SERVICEOUTPUT="$SERVICEOUTPUT$" -field NOTIFICATIONTYPE="$NOTIFICATIONTYPE$"
}

define command {
command_name notify-host-by-slack
command_line /usr/local/bin/slack_nagios.pl -field slack_channel=#channelname -field HOSTALIAS="$HOSTNAME$" -field HOSTSTATE="$HOSTSTATE$" -field HOSTOUTPUT="$HOSTOUTPUT$" -field NOTIFICATIONTYPE="$NOTIFICATIONTYPE$"
}

  • nagiosのconfigchekアンドrestart

service nagios checkconfig
service nagios restart

  • あとはnagiosのコンパネからテスト用(配信対象)のサービスに入り、[今すぐ通知する]からテストすればOkay。

メモを書くのすら長かった。。。