ふかふかブログ

興味のあることについてゆる~く書きます

Splatoon2のスケジュールをGoogle カレンダーで確認しよう

---2021/07/07追記---

現在は動かなくなっています。

---追記終わり---

全国1億人のスプラトゥーンプレイヤーの皆さんこんにちは。

上記ツイートの通りですが、ツイートに貼ってあるikalendar.herokuapp.comの内容をみてもピンとこない人向けにGoogle カレンダーで連携する方法を解説したいと思います。

ikalendar.herokuapp.comではクエリを使って自分に必要な情報に絞ることが可能です。

すべて上げるときりがないので本エントリではいくつかのパターンに分けてイメージが付きやすいように画像付きで紹介します。

Google カレンダーへのカレンダー追加方法

画像のURLを追加から、URLを追加します。

追加するURLは取得したい情報によって変わってくるので後述します。

追加したタイミングでは名前がURLのままなので分かりづらいですが設定からカレンダーの名前は変更できます。 f:id:nohararc:20190127160914p:plain

全ルール取得したい

ikalendar.herokuapp.comの通り、

以下のURLを追加する

https://ikalendar.herokuapp.com/ical/all.ics

f:id:nohararc:20190127153339p:plain

ガチマッチの予定をすべて取得したい

以下のURLを追加する

https://ikalendar.herokuapp.com/ical/all.ics?mode=gachi&title_format=%25%7bgachi%3arule%7d%3a%20%25%7bgachi%3amap1%7d%2c%20%25%7bgachi%3amap2%7d

f:id:nohararc:20190127154104p:plain

ガチマッチ&エリアのスケジュールを取得したい

以下のURLを追加する

https://ikalendar.herokuapp.com/ical/all.ics?mode=gachi&rule=splat_zones&title_format=%25%7bgachi%3arule%7d%3a%20%25%7bgachi%3amap1%7d%2c%20%25%7bgachi%3amap2%7d

f:id:nohararc:20190127155744p:plain

特定のルールのスケジュールのみ取得したい

ガチマッチ・リーグマッチの予定2つのカレンダーを追加し同時に追加する

「ガチマッチ&エリアのスケジュールを取得したい」+ 応用で「リグマ&エリア」を追加してやればよい

「リグマ&エリア」のURLを追加し、「ガチマッチ&エリア」のカレンダーと同時表示する

https://ikalendar.herokuapp.com/ical/all.ics?mode=league&rule=splat_zones&title_format=%25%7bleague%3arule%7d%3a%20%25%7bleague%3amap1%7d%2c%20%25%7bleague%3amap2%7d%0d%0a

f:id:nohararc:20190127160436p:plain

ここで紹介していないパラメータとして、description_formatも指定できます。

詳細はikalendar.herokuapp.comを確認ください。

番外編

LINE版

Vim

github.com

Jupyter notebookでもVim scriptが書きたい!

この記事は、Vim Advent Calendar 2018 その2 1日目の記事です。

Vim その2 Advent Calendar 2018 - Qiita

皆さん、Jupyter notebookでVim scriptが書きたくなる時があると思います。

Jupyter notebookはKernelと呼ばれるものを差し替えることでPython以外も動作させることができます。

というわけで、Vim script kernel作ってみました。

動作確認はWindows10でのみ行っていますが、ほかのOSでも動くと思います。

完成図

f:id:nohararc:20181130234158p:plain

実装

json(connection)ファイル

{"argv":["python","-m","vim-kernel", "-f", "{connection_file}"],
 "display_name":"Vim"
}

python(kernel)ファイル

from ipykernel.kernelbase import Kernel
from subprocess import Popen, STDOUT, PIPE


class Vim(Kernel):
    implementation = 'Vim'
    implementation_version = '0.1'
    language = 'no-op'
    language_version = '0.1'
    language_info = {'name': 'Vim', 'mimetype': 'text/plain'}
    banner = 'Vim script'
    _d = {}
    def do_execute(self, code, silent, store_history=True,
             user_expressions=None, allow_stdin=False):

        with open('prog.vim', 'w') as f:
            f.write("\n".join(code.splitlines()))

        p = Popen(['vim', '-X', '-N', '-u', 'NONE', '-i', 'NONE', '-V1', '-e', '-s', '-S', 'prog.vim', '+qall!'], stdout=PIPE, stderr=STDOUT, shell=True)
        p.wait()
        exitcode = p.returncode
        output = p.communicate()[0].decode()
        self.send_response(self.iopub_socket, 'stream', {'name': 'stdout', 'text': output})
        return {'status': 'ok',
                'execution_count': self.execution_count,
                'payload': [],
                'user_expressions': {},
               }

if __name__ == '__main__':
    from ipykernel.kernelapp import IPKernelApp
    IPKernelApp.launch_instance(kernel_class=Vim)

2018/01/08追記

なんとあのmattnさんが改良版を作ってくださいました。

Vim scriptカーネルのインストール方法も詳細に記載されいているので試したい方はこちらを参照ください

Vim script で機械学習 - Qiita

まとめ

意外と簡単にJupyter kernelを作ることができました。

このkernelがVIm script普及拡大の一助となれば幸いです。

以下参考にしたもの

jupyter kernel作り方

Making kernels for Jupyter — jupyter_client 6.0.0.dev documentation

Vim script

Vimスクリプト基礎文法最速マスター - 永遠に未完成

vimのコマンド

$ vim -X -N -u NONE -i NONE -V1 -e -s -S prog.vim +qall!

wandboxから拝借

gobgp同士でebgp接続

gobgpのバイナリを落としてきてebgp接続するまでの手順

構成図

                      192.168.33.0/24
    AS65001                                AS65002
+----------------+                   +----------------+
|                |      ebgp         |                |
|                |  <------------>   |                |
|                |.21             .22|                |
|                +-------------------+                |
+----------------+                   +----------------+

wgetでバイナリを落とす

両ノードで以下のコマン打つ

$ wget https://github.com/osrg/gobgp/releases/download/v1.33/gobgp_1.33_linux_amd64.tar.gz
$ tar xzf gobgp_1.33_linux_amd64.tar.gz

gobgpd.confを書く

.21側

[global.config]
  as = 65001
  router-id = "192.168.33.21"

[[neighbors]]
  [neighbors.config]
    neighbor-address = "192.168.33.22"
    peer-as = 65002

.22側

[global.config]
  as = 65002
  router-id = "192.168.33.22"

[[neighbors]]
  [neighbors.config]
    neighbor-address = "192.168.33.21"
    peer-as = 65001

gobgpを起動する

両ノードで以下のコマンドを打つ

$  sudo -E ./gobgpd -f gobgpd.conf

動作確認

ネイバーが確立されている

$ ./gobgp neighbor
Peer             AS  Up/Down State       |#Received  Accepted
192.168.33.22 65002 00:03:01 Establ      |        0         0

keepaliveは30秒間隔

sudo tcpdump -i enp0s8 tcp port bgp -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s8, link-type EN10MB (Ethernet), capture size 262144 bytes
07:51:45.797742 IP 192.168.33.21.bgp > 192.168.33.22.57554: Flags [P.], seq 2993027708:2993027727, ack 2208320632, win 114, options [nop,nop,TS val 293637 ecr 6968370], length 19: BGP
07:51:45.798091 IP 192.168.33.22.57554 > 192.168.33.21.bgp: Flags [.], ack 19, win 115, options [nop,nop,TS val 6998159 ecr 293637], length 0
07:51:46.008469 IP 192.168.33.22.57554 > 192.168.33.21.bgp: Flags [P.], seq 1:20, ack 19, win 115, options [nop,nop,TS val 6998369 ecr 293637], length 19: BGP
07:51:46.008552 IP 192.168.33.21.bgp > 192.168.33.22.57554: Flags [.], ack 20, win 114, options [nop,nop,TS val 293848 ecr 6998369], length 0

07:53:15.798364 IP 192.168.33.21.bgp > 192.168.33.22.57554: Flags [P.], seq 57:76, ack 58, win 114, options [nop,nop,TS val 383638 ecr 7058370], length 19: BGP
07:53:15.798969 IP 192.168.33.22.57554 > 192.168.33.21.bgp: Flags [.], ack 76, win 115, options [nop,nop,TS val 7088114 ecr 383638], length 0
07:53:16.053562 IP 192.168.33.22.57554 > 192.168.33.21.bgp: Flags [P.], seq 58:77, ack 76, win 115, options [nop,nop,TS val 7088369 ecr 383638], length 19: BGP
07:53:16.053599 IP 192.168.33.21.bgp > 192.168.33.22.57554: Flags [.], ack 77, win 114, options [nop,nop,TS val 383893 ecr 7088369], length 0

07:52:45.797160 IP 192.168.33.21.bgp > 192.168.33.22.57554: Flags [P.], seq 38:57, ack 39, win 114, options [nop,nop,TS val 353637 ecr 7028370], length 19: BGP
07:52:45.797508 IP 192.168.33.22.57554 > 192.168.33.21.bgp: Flags [.], ack 57, win 115, options [nop,nop,TS val 7058128 ecr 353637], length 0
07:52:46.040236 IP 192.168.33.22.57554 > 192.168.33.21.bgp: Flags [P.], seq 39:58, ack 57, win 115, options [nop,nop,TS val 7058370 ecr 353637], length 19: BGP
07:52:46.040318 IP 192.168.33.21.bgp > 192.168.33.22.57554: Flags [.], ack 58, win 114, options [nop,nop,TS val 353880 ecr 7058370], length 0

動作環境

$ cat /etc/redhat-release
CentOS Linux release 7.1.1503 (Core)
$ ./gobgp --version
gobgp version 1.33

Ansibleの出力を弄る

公式情報 : Callback Plugins

以下のようなことができる

  1. 通常の出力に実行時間などの追加情報をいれる
  2. 通常の出力形式をjson等に変更する
  3. 自分でpluginを作ってやりたい放題する
  4. 出力をslackやmailに流す

以下、1, 2, 3を試す。

1. 通常の出力に実行時間などの追加情報をいれる

実行にかかった時間を出力してみる
ansible.cfgにcallback_whitelist = timerを追加
出力

~snip~
Playbook run took 0 days, 0 hours, 0 minutes, 4 seconds

2. 通常の出力形式をjson等に変更する

出力形式をjsonに変更してみる
ansible.cfgにstdout_callback = jsonを追加 出力

~snip~
"stats": {
        "192.168.33.12": {
            "changed": 0,
            "failures": 0,
            "ok": 2,
            "skipped": 0,
            "unreachable": 0
        }
    }
}

3. 自分でpluginを作ってやりたい放題する

公式ページCallback Plugins を参考にcallback_pluginsというフォルダを作り、その中にpythonでコードを記述していきます。

書き方等はドキュメントを探すよりも実際のコードを見たほうが早いと思います。

今回は、playbookを実行時にplaybook名を出力してみます。

ansible.cftにcallback_whitelist = save2fileを追記の上、以下のファイルを作成する

callback_plugins/save2file.py

import os

from ansible.module_utils.urls import open_url
from ansible.plugins.callback import CallbackBase


class CallbackModule(CallbackBase):
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'notification'
    CALLBACK_NAME = 'save2file'
    CALLBACK_NEEDS_WHITELIST = True

    def __init__(self, display=None):

        super(CallbackModule, self).__init__(display=display)

        self.playbook_name = None

    def v2_playbook_on_start(self, playbook):
        self.playbook_name = os.path.basename(playbook._file_name)
        print(self.playbook_name)

出力

host1.yml  ← playbook名

PLAY [host1] *******************************************************************

TASK [Gathering Facts] *********************************************************
~snip~

期待通りの出力になっています。
v2_playbook_on_startのほかにも関数はあるので既存のコードを参考にいろいろ試してみると面白いかもしれません。

jinja2で繰り返しのテキストを生成する

flask, ansibleでよくjinja2使っているのですが、単体で使ったことがなかったのでメモ

繰り返しのテキストを生成する2パターンを試した

テンプレートファイルをインポートして表示するパターン

ググったらよく出てくるパターン、説明不要

ソースコード

import jinja2
from jinja2 import Template, Environment, FileSystemLoader

env = Environment(loader=FileSystemLoader('./', encoding='utf8'))
tmpl = env.get_template('temp.txt')

weapons = ["スシ", "プラコラ"]
print(tmpl.render(weapons=weapons))

・テンプレートファイル(temp.txt)

{% for w in weapons %}
{
  "type": "message",
  "message": {
    "type": "text",
    "text": "{{ w }}"
  }
},{% endfor %}

・出力

{
  "type": "message",
  "message": {
    "type": "text",
    "text": "スシ" 
  }
},
{
  "type": "message",
  "message": {
    "type": "text",
    "text": "プラコラ"
  }
},

テンプレートをソースコード内で生成する方法

わからなかったので調べた。
jinja2公式によるとfrom_stringというものがあるらしい。

ソースコード

import jinja2
from jinja2 import Template, Environment

temp = """
{% for w in weapons %}
{
  "type": "message",
  "message": {
    "type": "text",
    "text": "{{ w }}"
  }
},{% endfor %}
"""
weapons = ["スシ", "プラコラ"]
tmpl = Environment().from_string(temp)
print(tmpl.render(weapons=weapons))

・出力
1つめのパターンと同じなので省略

ブロードキャストコマンドとしてのansible

複数のホストに入って同じコマンドの結果が欲しいシチュエーションは多いと思います。
Tera Termのブロードキャストコマンドやシェルスクリプトでがんばってもいいのですが、今回はansibleでやってみます。

構成としては、ansible対象ホストにubuntucentosを一台ずつ用意しています。
ansibleのバージョンは2.4で検証してます。

まずは簡単な例から、hostnameを出力するだけのパターン。 -mでモジュールを指定して、-aで引数を渡しています。

ansible -i hosts vagrant -u vagrant -k -m shell -a "hostname"
SSH password:
192.168.33.11 | SUCCESS | rc=0 >>
vagrant-centos

192.168.33.12 | SUCCESS | rc=0 >>
vagrant-ubuntu-trusty-64

ちなみにplaybookとして書くとこう
$ ansible-playbook -i hosts hostname.yml -k -u vagrant

# hostname.yml
---
- hosts: vagrant
  tasks:
  - name: echo hostname
    shell: hostname
    register: result
  - debug: var=result.stdout

次に、上記で書いたplaybookを実行したうえで値を別のplaybookで流用したい場合。
例として、ansible実行ホストのカレントディレクトリにtemp.logとして出力するplaybookを書いてみます。
ポイントは - {{hostvars['192.168.33.1x']['result']['stdout']}}で別のplaybookの値を参照している部分 - connection: localでローカルに対して実行している点

ansible-playbook -i hosts local.yml -k -u vagrant

# local.yml
---
- import_playbook: hostname.yml
- hosts: localhost
  connection: local
  tasks:
    - name: log export
      copy:
        mode: 0644
        dest: "./temp.log"
        content: "{{hostvars['192.168.33.11']['result']['stdout']}}\n{{hostvars['192.168.33.12']['result']['stdout']}}/n"

出力結果

# temp.log
vagrant-centos
vagrant-ubuntu-trusty-64

まとめ

  • ansibleはワンライナーとしての使い方もできる
  • hostvarsを利用することで柔軟な書き方ができる

キーボード初心者がHHKB2つ買いました

先日、ノリと勢いでHHKBを2つ買いました。
初めは有線接続のPD-KB420Bを購入し、家で使用したその日に無線も欲しいなと思ってPD-KB620Bも買いました。

今まではキーボード安くてもいいや派だったのですが、 先日高いマウスMX ERGOを買ってしまったので流れでキーボードも新調しました。

有線無線が変わるだけでスペックとしては同等のようです。(詳しくは↓の公式HP)
個人的な感想としては、PD-KB620(Bluetooth)のほうがキー軽いと思っていたのですが、公式曰く同じとのこと。

どっちがおすすめか

値段は2018年3月現在で、PD-KB620(Bluetooth)が5000円程高かったです。
これを我慢できるのであれば、PD-KB620(Bluetooth)をお勧めします。
バッテリーは単三乾電池2本ですが、最悪USBポートからの給電にも対応しているので。

ちょっとした不具合

PD-KB620(Bluetooth)のほうで、PCとのBluetooth接続がちょくちょく切れるということがありました。 詳しい原因は追えていませんが古い無線キーボード(私の場合はLogicool)のドライバを消してPC再起動でその後問題なく動いています。

皆さんもいいキーボードを買って快適なVim活をしましょう!

Happy Hacking Keyboard HHKB Professional JP | 仕様 | |PFU ← PD-KB420
Happy Hacking Keyboard HHKB Professional BT | 仕様 | |PFU ← PD-KB420(Bluetooth)