2019/06/05(水)【雨量観測】XRAINのスクリーンショットを会社Slackに投稿するPerlスクリプト

天気情報が流れるチャンネルが会社のSlackにあるのですが、XRAINのスクリーンショットも流れてきてほしくなったので作りました。

ちなみに大学生の頃は大学院の研究室訪問や大学院試験の費用を稼ぐために気象会社でアルバイトしていました。

SlackのtokenとチャンネルIDの取得情報はググってください。

$logo は会社のロゴと矢印が描かれた画像で、矢印の先にオフィスがあるという具合になっています。適当な画像を用意して置き換えてください。

CPANモジュール以外は何か特別にインストール必要なものはありませんでした。

#!/usr/bin/evn perl

use strict;
use warnings;
use utf8;
use Log::Log4perl qw(:easy);
use WWW::Mechanize::Chrome;
use File::Spec;
use File::Basename 'dirname';
use HTTP::Request::Common qw//;
use Encode;
use Furl qw//;
use JSON;
use Imager;
use DDP;

# TODO:
#  * 会社付近の色を取得して雨が降っているか判定

my $dirname = File::Spec->rel2abs(dirname($0));
my $rain_url = 'http://www.river.go.jp/x/krd0207010.php?lon=139.50406730175018&lat=35.674031853779084&opa=0.4&zoom=8&leg=0&intvl=5&ext=0';
my $fn= $dirname . "/xrain.png";
my $logo = $dirname . '/logo_and_arrow.png';

Log::Log4perl->easy_init($ERROR);
my $mech = WWW::Mechanize::Chrome->new(headless => 1);
$mech->viewport_size({ width => 760, height => 780 });
$mech->get($rain_url);
my $png = $mech->content_as_png;

open(my $fh, '>', $fn) or die $!;
binmode($fh);
print {$fh} $png;
close $fh;

my $img = Imager->new;
$img->read(file => $fn) or die $img->errstr;

$img->rubthrough(
  src  => do {
    my $tmp = Imager->new;
    $tmp->read(file => $logo) or die $tmp->errstr;
    $tmp;
  },
  tx => 460,
  ty => 527,
);

$img->rubthrough(
  src  => do {
    my $tmp = Imager->new;
    $tmp->read(file => $logo) or die $tmp->errstr;
    $tmp;
  },
  tx => 1203,
  ty => 527,
);

$img->rubthrough(
  src  => do {
  my $tmp = Imager->new;
    $tmp->read(file => $logo) or die $tmp->errstr;
    $tmp;
  },
  tx => 460,
  ty => 1170,
);
$img->rubthrough(
  src  => do {
    my $tmp = Imager->new;
    $tmp->read(file => $logo) or die $tmp->errstr;
    $tmp;
  },
  tx => 1203,
  ty => 1170,
);

$img->write(file => $fn) or die $img->errstr;

my $req = HTTP::Request::Common::POST('https://slack.com/api/files.upload',
  Content_Type => 'multipart/form-data',
  Content => [
    token    => 'xxxx',
    channels => 'xxxx',
    file     => [$fn],
    title    => Encode::encode_utf8('XRAIN自動投稿'),
    initial_comment => $rain_url,
  ]
);

my $res = Furl->new->request($req);
my $json = Encode::decode_json($res->content);

#p $json;

うまくいけば↓のように投稿されます。cronで定期実行させています。

スクリーンショット_2019-06-05_21_19_07.png

2018/01/03(水)【PWA】「ホーム画面に追加」の「Site cannot be installed: the page does not work offline」エラー対策

結論:serviceWorker用のJSファイルに「self.addEventListener('fetch', function(event) {});」と追記すれば直る。


自作のWebアプリで「ホーム画面に追加」機能を加えようと以下を用意しました。

HTMLのヘッダーで上記「manifest.json」を読み込むようにして、HTMLのフッターには以下のJSを追記。

window.addEventListener('load', function() {
    if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register("/serviceWorker.js")
            .then(function(registration) {
                console.log("Service worker registration succeeded: ", registration);
            }).catch(function(error) {
                console.warn("Service worker registration failed: ", error);
            });
    }
    else {
        console.log('Service workers are not supported.');
    }
});

しかし、Chromeのコンソールで「Add to homescreen」をクリックしても「Site cannot be installed: the page does not work offline」のエラーが表示されます。(画像の右端の下部から手動でも Add to homescreen できる)

スクリーンショット 2018-01-03 0.08.11.png

「ホーム画面に追加」機能には影響ないのではなかろうかと思って半日くらい待ってみましたが、一向に「ホーム画面に追加」バナーが出てきません。

さすがにおかしいと思って調べると、ServiceWorker用のJSファイルに「self.addEventListener('fetch', function(event) {});」と追記する必要があるようでした。

Chrome looks for the fetch event handler as a minimal test for offline capability. Designing a proper caching strategy is not simple, so deploying an 'empty' or placeholder service worker is a valid strategy to get started. Just make sure you have a fetch event handler.

https://love2dev.com/blog/is-your-progressive-web-app-may-not-prompting-the-customer-to-add-to-home-screen/より引用。

追加してブラウザキャッシュを飛ばしてやると、すぐに Android の Chrome で「ホーム画面に追加」バナーが出てきました。(PC版の Chrome では Chromeアプリとして登録されました。)

PC版では「このサイトをシェルフに追加するといつでも使えるようになります。」という、利用者からすると「なんのこっちゃ」という感じのメッセージが出てきました。(将来のバージョンではいろいろ変わってそう)

スクリーンショット 2018-01-02 22.59.51.png

2018/01/01(月)2018年の目標

スポーツ

卓球:気分転換にたまにやる感じ

去年の2月に人生で初めて卓球をまともにやって、サークルに入って、卓球教室で技術を磨きつつ練習を重ねて秋の区民大会に出場しました。カット主戦でいきましたが大会では1勝もできず、1セット取るだけでいっぱいいっぱいでした。今年は月に1回くらい気分転換にやるくらいのあんばいでいきたい。

野球:月1でいいか

経験は12年くらいで特に学びもなくなってきて、野球は月1でいいかなという具合です。

テニス:区民大会で勝ちたい

去年の9月中旬に始めました。自主トレしつつテニス教室に週2で通っていますがまだサーブに苦しんでいます。サーブが安定して教室の中級に上がれたくらいでサークルにも入りたいと思います。やはり教室よりスポーツを通じて他者と仲良くなりやすいサークルのほうが楽しいですからね。

あとは、秋の区民大会に出たい。出るからには勝ちたいですね。

  1. サーブを安定させる
  2. 初級 → 中級 に上がる
  3. テニスサークルに入る
  4. 秋季区民大会出場

Web開発

スポーツ事業を支えるサービスの開発

年初最初の副業がこれです。知人から依頼されて去年頃から話を詰めていました。もうデザインを考えねばならないというフェーズです。スポーツによって人生を支えられてきたので、今度は私らが支える番です。

朗読部

朗読Webアプリです。すでにブログとツイッターは開設してあるので、あとは本体を作るのみです。大ヒットはまったく狙っていなくて、「すごい名前生成器」みたいに、流行り廃りに負けない、一定のアクセスがずっと続く系のコンテンツになれば成功かと思っています。

お金を貯める

去年は卓球・テニスを始めたせいもあってかなりお金を使ってしまいました。でも今習っておけば、何十年も楽しめるスポーツなので投資効果は高いと考えてやっている面もあります。今年は最低でも100万円は貯めたい。でも、確実に将来にプラスになると確信できることであれば、自信への投資も積極的に行いたい。

2018年もがんばるぞー!

2014/12/20(土)Web Speech API と Twitter n-gram を利用した英語発音矯正ゲーム

4月からは自分が研究室で唯一の日本人になってしまうので、英語の発音のトレーニングをひたすら楽しく積めるWebアプリケーションを研究の合間に作っていました。

「えいごのはつおんとれーにんぐ」 https://pron.chobitool.com/

開発は6日間ぐらいで、そのうち素材集めに3日ほど費やしました。

Web Speech API に音声認識と音声合成のインターフェースがあるので、これらをフル活用しました。出題される問題は Twitter n-gram の高頻度の表現から抽出しています。

いい練習になるので、マイクとChromeがあればどうぞ。

オペレーターズサイドという音声認識ゲームに触発されて「なんだとはなんだゲーム」も作りました。

学生寄宿舎の壁が薄すぎて小さい声でしか練習できないのが辛いところです。

2014/09/20(土)KindleGenで縦書き

以下のCSSを用いてKindleGenでmobiファイルを生成したら縦書きになりました。ハマった点は、HTML5のノリでCSSの「type="text/css"」を省略するとCSSがまったく適用されなくなる点。別のリーディングシステム(Readiumなど)では正常に縦書きで表示されるため、問題の特定に2時間以上かかりました。

自作ライブラリである程度のCSSを自動生成している関係でp要素のCSSは上書きしている形になっています。

@charset "UTF-8";

body
{
    -webkit-writing-mode: vertical-rl;
    -epub-writing-mode:   vertical-rl;
    writing-mode:         vertical-rl;

    -webkit-text-orientation: vertical-right;
    -epub-text-orientation:   vertical-right;
    text-orientation:         vertical-right;

    line-height: 1.8;
    letter-spacing: 0.1em;

    -webkit-word-break: break-all;
    -epub-word-break: break-all;
    word-break: break-all;

    -webkit-line-break: strict;
    -epub-line-break: strict;
    line-break: strict;
}

.tcy
{
    letter-spacing: 0;

    -webkit-text-combine: horizontal;
    -epub-text-combine: horizontal;
    text-combine: horizontal;

    -webkit-text-combine-horizontal: all;
    text-combine-horizontal: all;
}

p
{
    margin: 0;
    padding: 0;
    text-indent: 1em;
}

.dialog
{
    text-indent: 0em;
}

h2
{
    margin-left: 3em;
    margin-right: 2em;
    text-indent: 3em;
    font-size: large;
    font-weight: normal;
}

p
{
    margin: 0;
    padding: 0;
    text-indent: 1em;
}

.dialog
{
    text-indent: 0.5em;
}

Kindle PWでの表示 Nexus7での表示 iPhone5Sでの表示

スクリーンショットはKindle Paperwhite 2013、Nexus7 2013、iPhone5Sの順番ですが、見事に表示がバラバラ。最後の「!」2つはU+203Cの感嘆符です。Kindleでは普通の「!」を縦中横させるほうがいい感じですな。

Kindle PWとNexus7ならある程度は表示を揃えられそうなので、この2つを優先しますかね。