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

もぐてっく

人は1つ歳を取る度、1ビットづつ大きくなれると信じてた。

TL内を検索するmikutteプラグインを作ったよ

mikutter

何これ?

TL内の文字列検索を実現するプラグインです。

「くぽぉwwwww相変わらず○○殿のネタ振りは流石でござるなwwそれでは某もインターネットダジャレおじさんとして皆に手本を見せねばなりませぬのwwwではここは『ゴマ豆腐』など・・・いやいや、もう一つひねりを加えて『PDドライブ』はいかがか?wwwふむ。少々の隙もあり、皆のツッコミも期待できる我ながら名回答でござるなwwwwさて、まずはお題をリツイート・・・あれ?どこ行ったでござるか???お題ツイート殿~?」

って時に便利です。

インストール

GitHubからzipファイルをダウンロードして適当なディレクトリに展開して下さい。

https://github.com/moguno/mikutter-find-tl

※mikutterプラグインマネージャ"Packaged"で"moguno"を検索してインストールするのもおすすめです。

使い方

TLのメッセージを右クリックして、メニューから「TL検索」を選択してください。

f:id:moguno:20160517101716p:plain

TLの上部に検索ボックスが出るので、探したい文字列を入力してください。
文字列を含むメッセージがTLの上部に出てくるハズです。

f:id:moguno:20160517101731p:plain

TL内検索コマンドをショートカットにアサインすると便利です。

設定

TL検索

f:id:moguno:20160517102059p:plain

  • マッチしたツイートのスタイル

検索にマッチしたメッセージのフォントと背景色を設定します。

Windows 10 Insider Previewの"Bash on Ubuntu on Windows"をハンズオン!

Windows 10 14316

とうとうWindowsでもLinuxっぽいサブシステムがサポートされるということで、早速Insider Previewビルド14316を触ってみました!
(14316が配信されてからウチに降ってくるまで3日のタイムラグがあって、待ってる間約2分周期でWindowsアップデートを確認してたので眠いです。)

前情報によるとコンソールアプリはだいたい動く。Xのクライアントアプリも動くっぽいってことで、今回はちょっと意地悪にカーネルに近い部分を見ていこうと思います。

/devを見てみる

一部情報が取れないファイルがいますが、こんな感じでした。

root@localhost:~# ll /dev
ls: cannot access /dev/tty0: Invalid argument
ls: cannot access /dev/adss: Operation not permitted
total 7
drwxr-xr-x 2 root root    0 Apr 10 01:53 ./
drwxrwxr-x 2 root root    0 Jan  1  1970 ../
?????????? ? ?    ?       ?            ? adss
drwxr-xr-x 2 root root    0 Apr 10 01:53 block/
-rwxr--r-- 2 1000 1003    0 Apr 10 01:53 fb0*
drwxr-xr-x 2 root root    0 Apr 10 01:53 input/
crw------- 1 root 1007 0, 0 Apr 10 01:53 kmsg
?--------- 0 root root    0 Jan  1  1970 null
crw-rw-rw- 1 root tty  5, 2 Apr 10 01:53 ptmx
drwxr-xr-x 2 root root    0 Apr 10 01:53 pts/
crw-rw-rw- 1 root root 1, 8 Apr 10 01:53 random
lrwxrwxrwx 2 root root    0 Apr 10 01:53 shm -> /run/shm
crw--w---- 1 1000 tty  5, 0 Apr 10 01:53 tty
?????????? ? ?    ?       ?            ? tty0
crw-rw-rw- 1 root root 1, 9 Apr 10 01:53 urandom
crw-rw-rw- 1 root root 0, 0 Apr 10 01:53 zero
root@localhost:~#

ブロックデバイスは空。

root@localhost:~# ll /dev/block/
total 1
drwxr-xr-x 2 root root 0 Apr 10 01:55 ./
drwxr-xr-x 2 root root 0 Apr 10 01:55 ../
root@localhost:~#

次にイベントデバイス。お、マウスが見えてますね。

root@localhost:~# ll /dev/input/
total 5
drwxr-xr-x 2 root root 0 Apr 10 01:56 ./
drwxr-xr-x 2 root root 0 Apr 10 01:56 ../
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 event0*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 event1*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 event2*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 event3*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 event4*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 event5*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 mice*
-rwxr--r-- 2 1000 1004 0 Apr 10 01:56 mouse0*
root@localhost:~#

早速試してみるも権限なし。残念。

root@localhost:~# cat /dev/input/mice
cat: /dev/input/mice: Operation not permitted
root@localhost:~#

ちなみに、フレームバッファ/dev/fb0も同様にダメでした。

root@localhost:~# echo 1 > /dev/fb0
bash: echo: write error: Operation not permitted
root@localhost:~#

マウントされてるファイルシステムを見てみる

各種仮想ファイルシステムがマウントされてます。

root@localhost:~# mount
rootfs on / type rootfs (ro,relatime)
tmpfs on /dev type tmpfs (rw,seclabel,nosuid,relatime,mode=755)
devpts on /dev/pts type devpts (rw,seclabel,relatime,mode=600)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,seclabel,relatime)
root@localhost:~#

/procを見てみる

デバイスドライバが追加する諸々がないのとプロセス数が少ないのとで、かなりシンプルですね。

root@localhost:~# ll /proc
total 4
dr-xr-xr-x 1 root root 0 Apr 10 01:21 ./
drwxrwxr-x 2 root root 0 Jan  1  1970 ../
dr-xr-xr-x 1 root root 0 Apr 10 02:02 1/
dr-xr-xr-x 1 root root 0 Apr 10 02:02 2/
dr-xr-xr-x 1 root root 0 Apr 10 02:03 64/
-r--r--r-- 1 root root 0 Apr 10 01:21 cmdline
-r--r--r-- 1 root root 0 Apr 10 01:21 cpuinfo
-r--r--r-- 1 root root 0 Apr 10 01:21 filesystems
-r--r--r-- 1 root root 0 Apr 10 01:21 interrupts
-r--r--r-- 1 root root 0 Apr 10 01:21 meminfo
lrwxrwxrwx 1 root root 0 Apr 10 01:21 mounts -> self/mounts
lrwxrwxrwx 1 root root 0 Apr 10 01:21 net -> /proc/self/net/
lrwxrwxrwx 1 root root 0 Apr 10 01:21 self -> /proc/64/
-r--r--r-- 1 root root 0 Apr 10 01:21 stat
dr-xr-xr-x 1 root root 0 Apr 10 01:21 sys/
-r--r--r-- 1 root root 0 Apr 10 01:21 uptime
-r--r--r-- 1 root root 0 Apr 10 01:21 version
root@localhost:~#

/proc/cpuinfoでCPUの情報がちゃんと取れてます。

root@localhost:~# cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 58
model name      :        Intel(R) Core(TM) i7-3667U CPU @ 2.00GHz
stepping        : 9
microcode       : 0xffffffff
cpu MHz         : 2494.000
cache size      : 256 KB
physical id     : 0
siblings        : 1
core id         : 0
cpu cores       : 1
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 6
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx rdtscp lm pni pclmulqdq monitor ssse3 cx16 sse4_1 sse4_2 popcnt aes xsave osxsave avx rdrand
bogomips        : 4988.00
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:
root@localhost:~#

/proc/sys/kernel/osreleaseを見てみます。
ちゃんとMS製を名乗ってますねw

root@localhost:~# cat /proc/sys/kernel/osrelease
3.4.0-Microsoft
root@localhost:~#

ファイルシステムを見ると結構充実してますね。

root@localhost:~# cat /proc/filesystems
nodev      sysfs
nodev      rootfs
nodev      bed
nodev      proc
nodev      tmpfs
nodev      binfmt_misc
nodev      debugfs
nodev      sockfs
nodev      usbfs
nodev      pipefs
nodev      anon_inodefs
nodev      devpts
ext3
ext2
ext4
nodev      ramfs
nodev      hugetlbfs
vfat
msdos
iso9660
fuseblk
nodev      fuse
nodev      fusectl
yaffs
yaffs2
nodev      mqueue
root@localhost:~#

iso9660fuseが気になるので試してみます。

fuseを使ってみる

とりあえずデバイスファイルがないので作成。

root@localhost:~# mknod fuse c 10 229
root@localhost:~# ll fuse
ls: cannot access fuse: No such file or directory
root@localhost:~#

ダメでした。

ISOファイルをマウントしてみる

root@localhost:~# mount -o bind -t iso9660 /mnt/c/Users/mogun/Downloads/archlinux-2016.04.01-dual.iso /media/
root@localhost:~# mount
/mnt/c/Users/mogun/Downloads/archlinux-2016.04.01-dual.iso on /media type none (rw,bind)

お!行けた?

root@localhost:~# ls -l /media/
total 0
root@localhost:~#

かなり残念。見えませんでした。
この後、Windowsを再起動してもisoのマウントは解除されず。
/etc/mtab(中身は空)を削除すると復旧しました。

initの実力とやらをみてみる

Windows起動時にinitの初期ルーチンが動いてデーモンが動くと便利です。お手軽にrc.localが動くか試してみます。

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

echo "test" > /tmp/test

exit 0

リブートするも/tmp/testは作成されず。残念。

sshサーバを動かしてみる

これが動けばmsys2でやってた「WindowsなのにsshしたらLinuxっぽい」環境が誕生します。

まず、足りて無いディレクトリを作ります。

root@localhost:~# mkdir /var/run/sshd
root@localhost:~# chmod 755 /var/run/sshd/

それからsshdを起動するも、デーモンは常駐せず。
デバッグモードで挙動を見てみます。

root@localhost:~# /usr/sbin/sshd -d
・・・
Connection from 127.0.0.1 port 49811 on 127.0.0.1 port 22
debug1: Client protocol version 2.0; client software version OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6
debug1: match: OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6 pat OpenSSH_6.6.1* compat 0x04000000
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6
chroot("/var/run/sshd"): Invalid argument [preauth]
debug1: do_cleanup [preauth]
debug1: monitor_read_log: child log fd closed
debug1: do_cleanup
debug1: Killing privsep child 104
debug1: audit_event: unhandled event 12
root@localhost:~#

どうもchrootが動いてないのがダメっぽいですね。残念。

擬似端末ってどうなのかしら

sshdで擬似端末の扱いも見たいと思ってたんですが作戦失敗。シンプルなtelnetdで試すことに。
inetutils-inetdとtelnetdをインストールしました。

straceで観察しつつ接続してみます。

[pid    51] open("/dev/ptmx", O_RDWR)   = 3
[pid    51] statfs("/dev/pts", 0x7ff5fffee140) = -1 EPERM (Operation not permitted)
[pid    51] statfs("/dev/", 0x7ff5fffee140) = -1 EPERM (Operation not permitted)
[pid    51] close(3)                    = 0
[pid    51] open("/dev/ptyp0", O_RDWR)  = -1 ENOENT (No such file or directory)
[pid    51] write(0, "telnetd: getpty: No such file or"..., 47) = 47

Unix98、BSD方式共にコケて諦めてますね。ぐぅ残念。

デーモンが動くかみてみる

こんなスクリプトを書いてデーモンになるか試してみました。

Process.daemon

loop {
        sleep 1
        open("/tmp/a.txt", "a") { |fp|
                fp.puts "test"
        }
}

おお、a.txtのサイズが増えていきます。成功です。

root@localhost:~# ll /tmp/a.txt
-rw-rw-rw- 1 root root 160 Apr 10 02:52 a.txt
root@localhost:~# ll /tmp/a.txt
-rw-rw-rw- 1 root root 170 Apr 10 02:52 a.txt

でも、Bash on Ubuntu on Windowsのウインドウを閉じるとデーモンになったrubyも死にますね。

SysV IPCを試してみる

root@localhost:~# ipcs

kernel not configured for shared memory

kernel not configured for semaphores

kernel not configured for message queues

root@localhost:~#

おっと。サポートされていない様です。最近のアプリでは使わないんですかね?
今業務で保守してるソフトはSysV IPCバリバリなので、Windows移植の話が来たら全力で蹴ろうと思います。

その他

なんとなくlsofでbashが開いてるファイルを確認してみた

root@localhost:~# lsof | grep sh
bash     43 root  cwd   unknown                                 /root (stat: No such file or directory)
bash     43 root  rtd   unknown                                 /proc/43/root (readlink: No such file or directory)
bash     43 root  txt       REG    0,0 1021112 1970324836978220 /bin/bash
bash     43 root  mem       REG    0,0                     3628 /bin/bash (path inode=1970324836978220)
bash     43 root  mem       REG    0,0                   288340 /lib/x86_64-linux-gnu/libnss_files-2.19.so (path inode=1970324837262932)
bash     43 root  mem       REG    0,0                   288552 /lib/x86_64-linux-gnu/libnss_nis-2.19.so (path inode=1970324837263144)
bash     43 root  mem       REG    0,0                   288484 /lib/x86_64-linux-gnu/libnsl-2.19.so (path inode=1970324837263076)
bash     43 root  mem       REG    0,0                   288364 /lib/x86_64-linux-gnu/libnss_compat-2.19.so (path inode=1970324837262956)
bash     43 root  mem       REG    0,0                   288510 /lib/x86_64-linux-gnu/libc-2.19.so (path inode=1970324837263102)
bash     43 root  mem       REG    0,0                   288373 /lib/x86_64-linux-gnu/libdl-2.19.so (path inode=1688849860552309)
bash     43 root  mem       REG    0,0                   288352 /lib/x86_64-linux-gnu/libtinfo.so.5.9 (path inode=1970324837262944)
bash     43 root  mem       REG    0,0                   288312 /lib/x86_64-linux-gnu/ld-2.19.so (path inode=2251799813973560)
bash     43 root  mem       REG    0,0                   328650 /usr/lib/locale/locale-archive (path inode=2814749767435210)
bash     43 root  mem       REG    0,0                   328744 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache (path inode=844424930460712)
bash     43 root    0u  unknown                                 /WINDOWS/console (stat: No such file or directory)
bash     43 root    1u  unknown                                 /WINDOWS/console (stat: No such file or directory)
bash     43 root    2u  unknown                                 /WINDOWS/console (stat: No such file or directory)
bash     43 root  255u  unknown                                 /WINDOWS/console (stat: No such file or directory)
root@localhost:~#

/WINDOWS/console辺りにハックの痕跡が見て取れます。

なんとなく/sysを覗いてみた

/sys/devices/virtual/net/eth0/addressで本当のMacアドレスが見えました。

root@localhost:/tmp# cat /sys/devices/virtual/net/eth0/address
08:00:27:d3:5c:6e

なんとなくls三兄弟

lsmod、lspci、lsusb全部ダメでございました。

root@localhost:~# lsmod
libkmod: ERROR ../libkmod/libkmod-module.c:1619 kmod_module_new_from_loaded: could not open /proc/modules: No such file or directory
Error: could not get list of modules: No such file or directory

root@localhost:~# lspci
pcilib: Cannot open /proc/bus/pci
lspci: Cannot find any working access method.

root@localhost:~# lsusb
unable to initialize libusb: -99
root@localhost:~#

なんとなくuptime

/proc/loadavgがなくて怒られました。/proc/uptimeは読めてるのでかなり惜しい。

root@localhost:~# uptime
Error: /proc must be mounted
  To mount /proc at boot you need an /etc/fstab line like:
      proc   /proc   proc    defaults
  In the meantime, run "mount proc /proc -t proc"
root@localhost:~#

なんとなくuname

root@localhost:~# uname -a
Linux localhost 3.4.0+ #1 PREEMPT Thu Aug 1 17:06:05 CST 2013 x86_64 x86_64 x86_64 GNU/Linux
root@localhost:~#

まとめ

現状はカーネルにお願いする機能の多くが使用不能っぽいです。
LXCのコンテナの中相当と考えるとそんなに違和感の無い結果かと思いました。

夏の正式リリースまでに色々面白いことが出来る様になるといいですね。

sshごしにgoogle-drive-ocamlfuseのOAuth認証を行う方法

google-drive-ocamlfuse 0.5.22

はじめに

ファイルサーバにGoogle Driveをマウントして、重要なファイルをバックアップする仕組みを作ろうとしています。

Google Driveのマウントにはgoogle-drive-ocamlfuseを使うことにしたのですが、このソフトはアカウント認証(OAuth)の際にGUIなブラウザを要求してきます。

うちのファイルサーバにはXが無いのでブラウザは表示不可です。
X転送するにしても認証のためだけにブラウザ(と大量のX関係の依存ライブラリ)をインストールするのは超イマイチ。

google-drive-ocamlfuseはヘッドレスモードが想定されていますが、新たにGoogle Appの登録をしないといけない?などで面倒っぽいです。
(ドキュメントにも「ピンチの時だけ使え」って書いてますし。)

などなどの制約を鑑みて、今回はちょっとしたハックでこの状況を切り抜けることにしました。

手順

設定者はMacWindowsからsshを用いてファイルサーバにログインしている想定です。

カレントディレクトリにfirefoxという名前のシェルスクリプトを作る。

google-drive-ocamlfuseはOAuth認証を行う際に、ブラウザとしてxdg-open、firefoxgoogle-chromeの順に実行ファイルを探します。

つまり、これらと同名のシェルスクリプトを用意すれば、google-drive-ocamlfuseのOAuthの認証シーケンスに介入することが出来ます。

今回は"firefox"と言うシェルスクリプトを作って、まんまとgoogle-drive-ocamlfuseを化かしてやろうと思います。

./firefox

#! /bin/sh

echo $* > /dev/stderr

このスクリプトが呼ばれる際、stdoutはどっかにリダイレクトされてて端末にメッセージが出せないので、stderrに出力する様にします。
パーミッションを付けるのをお忘れなく。

chmod 777 firefox

OAuth認証を行う。

さっき作った偽firefoxのいるディレクトリにパスを通しつつ、google-drive-ocamlfuseを起動してOAuth認証を開始します。

firefoxのおかげで、ブラウザが呼び出されるタイミングでhttps://accounts.google.comで始まる URLが表示されるはずです。

$ PATH=`pwd`:$PATH google-drive-ocamlfuse
/bin/sh: 1: xdg-open: not found
https://accounts.google.com/o/oauth2/auth?client_id=564921029129.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fgd-ocaml-auth.appspot.com%2Foauth2callback&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&response_type=code&access_type=offline&approval_prompt=force&state=ystNgUZ5iSKxd%2FlP7WQ4jolWLy5QbZyrTXXXXXXXX

この端末は閉じないでこのまま置いといてください。

手元のブラウザで認証を行う。

お手元の超リッチなクライアントPCで動くブラウザのアドレスバーに先ほどのアドレスを貼り付けて認証を行います。

f:id:moguno:20160324004444p:plain

認証後にこの画面に遷移したらOKです。

f:id:moguno:20160324004505p:plain

1分ほど待ってgoogle-drive-ocamlfuseを起動した端末に下記のメッセージが表示されればOAuth認証は成功です。

Access token retrieved correctly.

原理

(カミングスーン)

Multiverse-coreで新しいワールドを作ってる途中にSpigotが落ちる

Spigot1.9 Multiverse-core

こんな感じでワールド生成を開始したところ、約1分でSpigotが落ちました。

>mv create 1-9 NORMAL
[05:17:20 INFO]: CONSOLE: Starting creation of world '1-9'...
・・・
[05:17:20 INFO]: Preparing start region for level 4 (Seed: 7967941679464971899)
[05:17:22 INFO]: Preparing spawn area for 1-9, 0%
・・・
[05:18:21 INFO]: Preparing spawn area for 1-9, 53%
[05:18:22 ERROR]: The server has stopped responding!
[05:18:22 ERROR]: Please report this to http://www.spigotmc.org/
[05:18:22 ERROR]: Be sure to include ALL relevant console errors and Minecraft crash reports

どうもワールド生成中はスレッドが固まったと判断されて、60秒後にタイムアウトしてたみたいです。
タイムアウト時限は設定ファイルにあるので、変更してしまいます。

config-version: 8
settings:
 ・・・
  timeout-time: 60 ← 300秒にしました。

これで無事にワールドが生成されました。

Chromeで見てるページのURLをmikutterから投稿できるようにしたよ

mikutter Chrome

なにこれ?

古来、ブログとは、

狭義にはWorld Wide Web上のウェブページのURLとともに覚え書きや論評などを加えログ(記録)しているウェブサイトの一種である。「WebをLogする」という意味でWeblogウェブログ)と名付けられ、それが略されてBlog(ブログ)と呼ばれるようになった。(Wikipediaより)

であるからして、「マイクロブログ」と称されるTwitterのクライアントについてもWebブラウザとの密接な連携が不可欠なのである。

と、言うわけでChromeで見てるページのURLをmikutterから投稿できるようにしてみました。

インストール

GitHubからzipファイルをダウンロードして適当なディレクトリに展開して下さい。

GitHub - moguno/mikutter-webapi-hardpoint: Chromeとかと会話する用のWebAPIを提供する前提プラグイン。Chromeで今見てるページをmikutterのPostboxに入力するサンプル付き

※mikutterプラグインマネージャ"Packaged"で"moguno"を検索してインストールするのもおすすめですけどこれまだ動くんかな? ← ダメだったので直しました。

Chrome拡張のコンパイル

今回はChromeにボタンを追加するので、Chrome拡張のインストールを伴います。
大して手間じゃ無いのでソースだけ添付してユーザーさんにコンパイルしてもらうことにしました。
(バイナリの管理嫌い)

突然ですがここでニュースです(2016/3/5)

先日のChromeのアップデートから、野良拡張がインストール不能になりました。
セキュリティ上の都合だそうです。にゃあ。

仕方が無いので$5.00払って正式公開しました。

chrome.google.com

以下、せっかく頑張って書いたので残しておきます。
公開前のデバッグなどに有効な手順だと思います。

Chrome拡張ソースコードをどっかにコピーする。

アーカイブの中にあるchromeディレクトリをどこかにコピーしてください。
~/.mikutter以下だとChromeから見えなかったりするので。

chrome://extensionsを開いて、拡張機能タブを開く。

アドレスバーにchrome://extensionsと入力します。

f:id:moguno:20160221102100p:plain

こんな画面が出てくると思います。

f:id:moguno:20160221102353p:plain

デベロッパーモードを有効にする。

画面上部の「デベロッパーモード」を有効にしてください。

f:id:moguno:20160221102420p:plain

いくつかボタンが増えました。

f:id:moguno:20160221102500p:plain

拡張機能をパッケージ化する

増えたボタンから「拡張機能をパッケージ化...」ボタンを押下します。

f:id:moguno:20160221131729p:plain

ダイアログが出てくるので、先ほどのchromeディレクトリを指定して「拡張機能のパッケージ化」ボタンを押してください。

f:id:moguno:20160221102544p:plain

こんなメッセージが出ればOKです。

f:id:moguno:20160221102555p:plain

chromeディレクトリと同じ階層にchrome.crx、chrome.pem(今回使いません)ができています。

f:id:moguno:20160221132700p:plain

拡張のインストール

先ほどのchrome.pemをChrome拡張機能タブにドラッグアンドドロップします。
「ここにドロップすると、インストールされます」が表示されるエリアにポイっ!すると良いです。

f:id:moguno:20160221133029p:plain

やましいことは無いので、どうぞ「拡張機能を追加」ボタンを押してください。

f:id:moguno:20160221133139p:plain

無事インストールされて、みくったーちゃんボタンがツールバーに登録されたはずです。

f:id:moguno:20160221133242p:plain

使い方

これは!と思うページを見つけたら、みくったーちゃんボタンを押すだけです。

f:id:moguno:20160221133402p:plain

こんな感じでmikutterのポストボックスにタイトルとURLがコピーされます。
後は思う存分ふぁぼを稼いでください。

f:id:moguno:20160221133501p:plain

実は・・・、

Chromeとmikutterとの会話を実現するために、mikutterをWebサービス化すると言う技を今回考案しました。

mikutter-webapi-hardpointをインストールすると、mikutterにhttp://127.0.0.1:39080/testと言うエンドポイントが生えます。

Chromeのボタンを押すとhttp://127.0.0.1:39080/test?title=タイトル&url=URLをGETし、mikutterが受け取った情報をPostboxに挿入すると言う仕組みです。

このmikutterをWebサービス化する仕組みは他にも応用が効きそうなので、DSLを用意しました。

webapi DSL

Webサービスのエンドポイントを追加します。
req, resはそれぞれWEBrick::HTTPRequest、WEBrick::HTTPResponse オブジェクトとなっています。
ぶっちゃけWebrick::mount_proc()のラッパーなのでそっちを色々見てもらえれば。

今回のtestエンドポイントはこんな感じです。

webapi("test") { |req, res|
  message = ">#{req.query["title"].force_encoding("UTF-8")}\n#{req.query["url"].force_encoding("UTF-8")}\n"

  Plugin[:gtk].widgetof(Plugin::GUI::Postbox::cuscaded.values.first).post.buffer.text = message
}

Ubuntu15.10でterminologyを使う

Ubuntu15.10 Fluxbox terminology

ふと、mikutterをBot的に使うために必要最低限のパッケージで構成したコンテナを作りたいなと思いました。

ベースは Ubuntu Server15.10(大好き)。

vnc経由で軽量なウインドウマネージャと適当なターミナルを使えるようにして、後はmikutterのインストールかなと。

ウインドウマネージャはFluxbox。ターミナルはUbuntu15.04からパッケージ化された未来的オシャレ端末terminologyにしました。

そこでちょびっとハマった時のメモです。

terminologyがFluxboxのメニューに出てこない!

次のコマンドでFluxboxとterminologyをインストールしました。

apt-get install fluxbox terminology

しかし、Fluxboxのメニューにterminologyが追加されませんでした。

試しに別のターミナルxterm、gnome-terminalを入れるとメニュー登録される。
逆にデスクトップ環境XFCE4を導入するとterminologyがメニューにちゃんといる。

謎。

UbuntuにおけるGUIメニューシステム

調べてみると、Ubuntuにはアプリケーションをデスクトップ環境のメニューに追加する仕組みが大きく2系統あることがわかりました。

freedesktop.org

デスクトップ環境を設計する上で、守ったほうがいいお約束をfreedesktop.orgと言う団体がまとめています。
このお約束に沿っていれば、例えばGTK製アプリとQtアプリで連携が取れるようになったり、各種設定ファイルがGnomeKDEで共有出来たりします。

ランチャーのメニュー項目についてもfreedesktop.orgに規定があり、アプリケーションはメニュー項目を定義した*.desktopファイルを用意することで、freedesktop準拠のデスクトップ環境のメニューにアプリケーションを登録できます。

先ほどのXFCE4も freedesktop.org準拠のデスクトップ環境です。

Debian Menu System

とは言え、昔ながらのデスクトップ環境(とかランチャー付きのウインドウマネージャ)はfreedesktop.orgに準拠していないものも多いです。

これらのデスクトップ環境では、ユーザ自身がメニュー定義を編集してアプリケーションを登録する必要があります。

それはさすがに面倒だよねということで、Debian系のディストリビューションにはDebian Menu Systemと言う仕組みがあります。

これはfreedesktop.orgのdesktopファイルと同等に、アプリケーション提供側がメニューファイルを用意します。
そしてupdate-menuコマンドでメニューファイルを元に各種デスクトップ環境用のメニュー定義が生成できるというものです。

古き良きBlackbokの流れを組むFluxboxはこっちのグループです。

つまり

今回のterminologyのパッケージにはfreedesktop.orgのterminology.desktopは収録されていたけれど、Debian Menu Systemのメニューファイルが入っていなかったのが原因です。

対策

Debian Menu Systemのメニューファイルを書きました。

/usr/share/menu/terminology

?package(terminology): \
        needs="X11" \
        section="Applications/Terminal Emulators" \
        title="Terminology" \
        command="/usr/bin/terminology" \

めっちゃかっこいい

無事、Fluxboxでterminologyが起動できました。
カーソルが怪しい青白の光を放っていたり、ベルの代わりに赤色灯が回ったりします。
Fluxboxのテーマともあつらえたように合ってますね。かっこいい。

f:id:moguno:20160214222225p:plain

Yet Another 実行中のmikutterにコードを流し込むやつを作ったよ

mikutter

何これ?

明けましておめでとうございます。

これは「あー正月ってテレビもつまんないしマジすることないよねー」カレンダー (なにそれ?)1日目の記事です。(1年ぶり2記事目)


今回は「起動中のmikutterに外部から任意のコードを流し込むプラグイン&コマンド」を作ったのでその紹介をば。

これ、コンセプトは@toshi_aさんのmikutter-modeと同じで、プラグインを改造するたびにmikutterをいちいち再起動したくないよねと言うところです。

じゃあなんで再発明してんだよ溜まってるIssue処理しろよ最近お前の腹の出方ヤバイだろ痩せろよ?のかと言うと、

もぐのがMacDBusを動かせなかった

mikutter-modeがプロセス間通信に使っているLinux御用達フレームワークDBusが、もぐののMacではなんかエラーになるんですよね。
なので、今回は古のRuby標準ライブラリであるdrubyでプロセス間通信を実現しました。

もぐのがvim

mikutter-modeはEmacsLISPで実装されてる所がいっぱいあって、vimで使うにあたってよくわかんなかったので。
せっかくなので、エディタに依存しない仕組みにすることにしました。

(ちなみにmikutter-modeのvim移植は2GMonさんによる実装があったりします。)
github.com

インストール

GitHubからzipファイルをダウンロードして、プラグインディレクトリにmikutter-code-injectorと言うディレクトリ名で展開して下さい。

moguno/mikutter-code-injector · GitHub

※mikutterプラグインマネージャ"Packaged"で"moguno"を検索してインストールするのもおすすめです。

使い方

普通にmikutterを起動する。

ごく普通にmikutterを起動してください。

見た目には変化はありませんが、netstat -aするとこんな行が増えてたりします。

tcp6       0      0  localhost.39311        *.*                    LISTEN

コードを送り込む

~/.mikutter/plugin/mikutter-code-injector/にmktrと言うコマンドがあります。
そのmktrの標準入力にRubyコードを流し込んでみてください。
起動中のmikutterでコードが実行されます。

実行できるコードに制限はなく、mikutterのフル機能を操作できます。

仕組み的にはmikutterのトップレベルbindingをdrubyで公開しておいて、mktr側でそれを取得。
んで、取得したbindingのevalを呼ぶとmikutter側でコードが実行されると言う寸法です。

それでは試しに、コマンドラインからつぶやいてみましょう。

echo 'Service.primary.post(:message => "みくっ")' | ./mktr

f:id:moguno:20151121103409p:plain

ちゃんとつぶやけましたね。
速攻で複数人からふぁぼられてるのは弊TLの仕様です。

vimから使ってみる。

もぐのはvimスクリプトが書けない人なので、mikutter-modeの様なvimとの統合機能は作り込んでません。
て言うか、vimではこんな風に現在のバッファをmktrの標準入力に流し込むことが出来るので、これでいっかーな感じになってます。

:w !./mktr

これで本格的なプラグイン開発にも対応できますね。

f:id:moguno:20151121111310p:plain

現状の制限として、mikutter起動時のイベントon_bootはコード流し込み時には実行されません。
この辺はなにか工夫できたらいいなと思ってます。