動かざることバグの如し

近づきたいよ 君の理想に

nuxt ganerateで生成するディレクトリを変更する

nuxt.jsで静的ホスティングしたいときはnuxt ganerateコマンドを叩く(実際にはnpm run generate)

これでdistディレクトリ内に生成されるが、都合的に他のディレクトリに出力したい場合

やり方

nuxt.config.jsに以下追加

module.exports = {generate: {
    dir: "docs"
  }
}

これでdocs以下に生成されるようになった。

参考リンク

nuxt.js めも

インストール

$ vue init nuxt-community/starter-template <project-name>

ディレクトリ構造

├── assets アセットファイルたち
├── components Vue.js のコンポーネントファイル 基本いじらない?
├── layouts レイアウトファイル
├── middleware レンダリング前のカスタム関数を定義できる 最初はいじらなそう
├── node_modules いつもの
├── nuxt.config.js 設定ファイル
├── pages *.vueが入る
├── plugins JavaScript プラグイン すぐにはいじらない?
├── static 静的ファイル
└── store Vuex ストア のファイル 分からん

templateは必須

pages/index.vueを空にすると

NuxtServerError
render function or template not defined in component: pages/index.vue

ってなる

<template>
  <h1>hello</h1>
</template>

は必須

ルーティング

は自動生成される(ファイル的には)

  • pages/index.vue

/ pages 直下 の index. vue が 表示 さ れる /about pages 直下 の about. vue が 表示 さ れる /articles articles 配下 の index. vue が 表示 さ れる

nasum. Hello Nuxt!!: Vue.jsのサーバサイドレンダリングフレームワーク (Kindle の位置No.166-168). 楽描帳. Kindle 版.

/ pages 直下 の index. vue が 表示 さ れる /about pages 直下 の about. vue が 表示 さ れる /articles articles 配下 の index. vue が 表示 さ れる

nasum. Hello Nuxt!!: Vue.jsのサーバサイドレンダリングフレームワーク (Kindle の位置No.166-168). 楽描帳. Kindle 版.

iodineでVPN over DNSなVPN環境を構築する

iodineとは

iodineとはDNSパケットを利用してVPN通信を実現するVPN over DNSのネットワークシステムを実現するアプリケーション。

普通のVPNでええやんって思うかもしれないけど、IPsecVPNではファイアウォールの規制が厳しい環境だと使えないかもしれない。が、VPN over DNSではファイアウォールからはDNSリクエストにしか見えないので流石に通すしかなくて、規制されずに使えるって戦法。

ちなみにVPN over DNSを知った理由はmineoが通信を最適化(と言う名の改ざん)を始めてVPNもNGらしいので。

環境

サーバーのインストール

Ubuntuの場合はパッケージが用意されているので一発インスコ

apt install iodine

その他のディストーションのパッケージはココで確認して

サーバーの実行 iodineとiodinedの2つのコマンドがあるが、

  • iodined サーバー用コマンド
  • iodine クライアント用コマンド

なので注意

# iodined -f 192.168.1.100 example.com
  • -f フォアグラウンド デフォルトはデーモンで実行される。
  • 192.168.1.100 仮想ネットワーク上でiodinedが利用するIP VPN接続するクライアントは同ネットワークのIPが自動で割り当てられる。
  • example.comドメイン名は適当。このドメインのリクエストのみiodineは受け付ける。

起動時にパスワードの入力を求められるので入力

クライアントのインストール

同様にiodineをインストール

接続

# iodine -f -r x.x.x.x example.com
  • -fはフォアグラウンド起動
  • x.x.x.xはサーバーのグローバルIP
  • example.comはさっきサーバー起動時に指定したドメイン名と同じ
  • -r をつけると高速化するらしい

パスワードを聞かれるので入力してエンター。以下のようにConnection setup complete, transmitting dataって出れば成功

root@raspberrypi:~
Enter password: 
Opened dns0
Opened IPv4 UDP socket
Sending DNS queries for example.com to 207.148.72.26
Autodetecting DNS query type (use -T to override).
Using DNS type NULL queries
Version ok, both using protocol v 0x00000502. You are user #0
Setting IP of dns0 to 192.168.1.97
Setting MTU of dns0 to 1130
Server tunnel IP is 192.168.1.100
Skipping raw mode
Using EDNS0 extension
Switching upstream to codec Base128
Server switched upstream to codec Base128
No alternative downstream codec available, using default (Raw)
Switching to lazy mode for low-latency
Server switched to lazy mode
Autoprobing max downstream fragment size... (skip with -m fragsize)
768 ok.. ...1152 not ok.. 960 ok.. 1056 ok.. 1104 ok.. 1128 ok.. 1140 ok.. will use 1140-2=1138
Setting downstream fragment size to max 1138...
Connection setup complete, transmitting data.

うまくいくとクライアントからサーバーのVPN側のIPアドレスpingが通るはず

# ping 192.168.1.100
PING 192.168.1.100 (192.168.1.100) 56(84) bytes of data.
64 bytes from 192.168.1.100: icmp_seq=1 ttl=64 time=83.9 ms
64 bytes from 192.168.1.100: icmp_seq=2 ttl=64 time=75.6 ms
64 bytes from 192.168.1.100: icmp_seq=3 ttl=64 time=82.9 ms
64 bytes from 192.168.1.100: icmp_seq=4 ttl=64 time=75.4 ms

これでDNSトンネリングの完成

SSHトンネリング

実はこれだけではダメで、DNSの通信自体は暗号化されていないので危険である(たぶん

そこでSSHトンネリングを行う(正直この辺まだよくわかってない)

トンネリングは以下。クライアントからサーバーへSSHログインできるようにしておく必要がある。

ssh -D 9999 -N user@192.168.1.100
  • 9999はポート番号 任意
  • 192.168.1.100 はサーバーのVPN側のIPアドレス

接続

あとはクライアント側で

curl --socks5-hostname 127.0.0.1:9999 checkip.amazonaws.com

した時にサーバー側のIPが表示されればOK

うまくいかない

サーバー側で以下実行 eth0は適宜読み替える

# /etc/sysctl.conf に以下追記して sysctl -p
net.ipv4.ip_forward = 1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o dns0 -m state --state RELATED,ESTABLISHED
-j ACCEPT
iptables -A FORWARD -i dns0 -o eth0 -j ACCEPT

参考URL

YouTube Data API v3でサクッと動画検索

やりたいこと

キーワード叩いたら動画一覧が取得できる。

用意するもの

v3からキーが必須

GCPのAPIライブラリ一覧からYoutube Data APIを有効にする プロジェクトなかったら作る

次に https://console.developers.google.com/apis/credentials よりAPIキーを作成

  • 「認証情報の作成」をクリック
  • APIキー」を選択
  • そのままだと全部の権限が付与されてしまうので「キーの制限」より「YouTube Data API v3」を選択

API URL

公式ドキュメント参照して

ShangriLa Anime APIで遊ぶ

ShangriLa Anime APIというAPIをこの前知った。秋葉原IT戦略研究所というところが無料で出しているらしいが、結構データが豊富で面白い。ここのサークルは以前の技術書典で本買った記憶がある。

が、ドキュメントが幾つか分散していたのでまとめメモ

共通仕様

ここで記述するAPIの共通仕様

  • すべてGETパラメータ
  • httpで書いているがhttpsでも取得可能

アニメ一覧取得

:yearは2018のような西暦が入る以下はhttp://api.moemoe.tokyo/anime/v1/master/2018 の取得例

[
  {
    "id": 673,
    "title": "探偵オペラ ミルキィホームズ アルセーヌ 華麗なる欲望"
  },
  {
    "id": 674,
    "title": "アイドリッシュセブン"
  },
  {
    "id": 675,
    "title": "宇宙よりも遠い場所"
  },
  {
    "id": 676,
    "title": "ダメプリ ANIME CARAVAN"
  },
  {
    "id": 677,
    "title": "ラーメン大好き小泉さん"
  },
  {
    "id": 678,
    "title": "ゆるキャン△"
  },
(略)

:yearのあとに1〜4の数字をつけるとクールごとに取得できる。こちらはタイトルに加えてURLやTwitterアカウントも取得できる。以下は http://api.moemoe.tokyo/anime/v1/master/2018/1 の例

[
  {
    "title_short2": "",
    "twitter_account": "milkyholmes",
    "public_url": "https://sp.bushiroad.com/special_tv/",
    "title_short1": "ミルキィホームズ",
    "sex": 0,
    "twitter_hash_tag": "milkyholmes",
    "id": 673,
    "sequel": 5,
    "created_at": "2018-01-07 20:29:38.0",
    "city_name": "",
    "cours_id": 17,
    "title": "探偵オペラ ミルキィホームズ アルセーヌ 華麗なる欲望",
    "city_code": 0,
    "title_short3": "",
    "updated_at": "2018-01-07 20:29:38.0"
  },
  {
    "title_short2": "",
    "twitter_account": "iD7Mng_Ogami",
    "public_url": "http://idolish7.com/aninana/",
    "title_short1": "アイドリッシュセブン",
    "sex": 1,
    "twitter_hash_tag": "アイナナ",
    "id": 674,
    "sequel": 0,
    "created_at": "2018-01-07 20:29:38.0",
    "city_name": "",
    "cours_id": 17,
    "title": "アイドリッシュセブン",
    "city_code": 0,
    "title_short3": "",
    "updated_at": "2018-01-07 20:29:38.0"
  },
  {
    "title_short2": "",
    "twitter_account": "yorimoi",
    "public_url": "http://yorimoi.com/",
    "title_short1": "宇宙よりも遠い場所",
    "sex": 0,
    "twitter_hash_tag": "よりもい",
    "id": 675,
    "sequel": 0,
    "created_at": "2018-01-07 20:29:38.0",
    "city_name": "",
    "cours_id": 17,
    "title": "宇宙よりも遠い場所",
    "city_code": 0,
    "title_short3": "",
    "updated_at": "2018-01-07 20:29:38.0"
  },
  {
    "title_short2": "",
    "twitter_account": "damepri_anime",
    "public_url": "https://damepri-anime.jp/",
    "title_short1": "ダメプリ",
    "sex": 1,
    "twitter_hash_tag": "ダメプリ",
    "id": 676,
    "sequel": 0,
    "created_at": "2018-01-07 20:29:38.0",
    "city_name": "",
    "cours_id": 17,
    "title": "ダメプリ ANIME CARAVAN",
    "city_code": 0,
    "title_short3": "",
    "updated_at": "2018-01-07 20:29:38.0"
  },
  {
    "title_short2": "小泉さん",
    "twitter_account": "ramen_koizumi",
    "public_url": "http://ramen-koizumi.com/",
    "title_short1": "ラーメン大好き小泉さん",
    "sex": 0,
    "twitter_hash_tag": "ラーメン大好き小泉さん",
    "id": 677,
    "sequel": 0,
    "created_at": "2018-01-07 20:29:38.0",
    "city_name": "",
    "cours_id": 17,
    "title": "ラーメン大好き小泉さん",
    "city_code": 0,
    "title_short3": "",
    "updated_at": "2018-01-07 20:29:38.0"
  },
  {
    "title_short2": "",
    "twitter_account": "yurucamp_anime",
    "public_url": "http://yurucamp.jp/",
    "title_short1": "ゆるキャン△",
    "sex": 0,
    "twitter_hash_tag": "ゆるキャン",
    "id": 678,
    "sequel": 0,
    "created_at": "2018-01-07 20:29:38.0",
    "city_name": "",
    "cours_id": 17,
    "title": "ゆるキャン△",
    "city_code": 0,
    "title_short3": "",
    "updated_at": "2018-01-07 20:29:38.0"
  },
Property Value Required description Sample
id Number APIで管理するアニメ作品に割り当てられているユニークなID 125
title String アニメ作品名 "冴えない彼女の育てかた"
title_short1 String - アニメ作品名の略称1 "冴えカノ"
title_short2 String - アニメ作品名の略称2
title_short3 String - アニメ作品名の略称3
public_url String アニメ作品の公式URL "http://www.saenai.tv/"
twitter_account String ツイッターアカウント "saenai_heroine"
twitter_hash_tag String ツイッターハッシュタグ "saekano"
cours_id Number coursマスターのID 5
created_at String データの作成日時 "2015-01-08 09:37:01.0"
updated_at String データの更新日時 "2015-01-08 09:37:01.0"
sex Number - 男性向け=0, 女性向け=1 0
sequel Number - 続編モノの場合は1以上の数値が入る 0

Twitterフォロワー数取得

取得したいTwitterのアカウントのスクリーンネーム(@以降のやつ)をaccountsパラメータで渡す。カンマ区切りで渡すと複数アカウントを一括で取得できる。以下は https://api.moemoe.tokyo/anime/v1/twitter/follower/status?accounts=usagi_anime,kinmosa_anime,nganime の取得例

// 20180503221210
// https://api.moemoe.tokyo/anime/v1/twitter/follower/status?accounts=usagi_anime,kinmosa_anime,nganime

{
  "kinmosa_anime": {
    "follower": 97431,
    "updated_at": 1525274645
  },
  "usagi_anime": {
    "follower": 305795,
    "updated_at": 1525275187
  },
  "nganime": {
    "follower": 138999,
    "updated_at": 1525278006
  }
}

Twitterフォロワー数推移取得

:screen_nameにはTwitterのアカウント名が入る。こちらは複数不可

http://api.moemoe.tokyo/anime/v1/twitter/follower/history/daily?account=usagi_anime&days=30 のようにdaysをつけると取得にっすが増える。が最大39日前までっぽい。デフォルト7。

// 20180503222117
// http://api.moemoe.tokyo/anime/v1/twitter/follower/history/daily?account=usagi_anime&days=10

[
  {
    "follower": 305549,
    "updated_at": 1524417182,
    "yyyy-mm-dd": "2018-04-23"
  },
  {
    "follower": 305605,
    "updated_at": 1524503582,
    "yyyy-mm-dd": "2018-04-24"
  },
  {
    "follower": 305680,
    "updated_at": 1524589982,
    "yyyy-mm-dd": "2018-04-25"
  },
  {
    "follower": 305697,
    "updated_at": 1524676382,
    "yyyy-mm-dd": "2018-04-26"
  },
  {
    "follower": 305701,
    "updated_at": 1524762782,
    "yyyy-mm-dd": "2018-04-27"
  },
  {
    "follower": 305729,
    "updated_at": 1524849183,
    "yyyy-mm-dd": "2018-04-28"
  },
  {
    "follower": 305779,
    "updated_at": 1524935583,
    "yyyy-mm-dd": "2018-04-29"
  },
  {
    "follower": 305796,
    "updated_at": 1525021982,
    "yyyy-mm-dd": "2018-04-30"
  },
  {
    "follower": 305843,
    "updated_at": 1525108382,
    "yyyy-mm-dd": "2018-05-01"
  },
  {
    "follower": 305806,
    "updated_at": 1525194782,
    "yyyy-mm-dd": "2018-05-02"
  }
]