RaspberryPiにDockerをインストールする

昔できなかったよね?便利だなあ

sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

rootではなくユーザーも実行できるようにする

sudo gpasswd -a $(whoami) docker
sudo chgrp docker /var/run/docker.sock
sudo service docker restart

再起動すると良い

Rustで文字列にある文字列が含まれているかを判定する

なんのことはなくKotlinとかと同じで安心でした。

先頭がある文字で始まる場合を判定する

fn main() {
    assert_eq!("unko desu".starts_with("unko"), true);
    assert_eq!("unko desu".starts_with("desu"), false);
}

ある文字が含まれる場合を判定する

fn main() {
    assert_eq!("unko desu".contains("unko"), true);
    assert_eq!("unko desu".contains("desu"), true);
}

ある文字で終わる場合を判定する

fn main() {
    assert_eq!("unko desu".ends_with("unko"), false);
    assert_eq!("unko desu".ends_with("desu"), true);
}

参考

Rustで正規表現を使って文字列を置換する

正規表現は cargo add regex としてライブラリを入れる必要があります。なんかよくやる前方一致で消すようなやつはこんなもんで消せますが

use regex::Regex;

fn main() {
    let pattern = Regex::new("^.*/").unwrap();
    assert_eq!(pattern.replace("/aaa/bbb/ccc/ddd", ""), "ddd");
}

後方参照がないらしく(私の探し方が悪かったかな?)、JavaScriptで言うところの下記のような処理をするには

"This is a unko".replace(/^.*\s([a-z]+)$/, "I love $1");

Captures でマッチした部分を得て、それを使って文字列を組み上げるのが良いかと。

use regex::Regex;

fn main() {
    let pattern = Regex::new("^.*\\s([a-z]+)$").unwrap();
    let result = pattern.captures("This is a unko").unwrap();
    assert_eq!(format!("I love {}", result.get(1).unwrap().as_str()), "I love unko");
}

使うところそんなにないのかな

参考

RustでStringからu64にキャストする

キャストするだけならこんな感じで

fn main() {
    assert_eq!(String::from("1024").parse::<u64>().unwrap(), 1024 as u64);
}

str型はu8のスライス、String型はu8のベクタだそうな。parse の返り値は Result なんで unwrap() しとります。文字列は結構深いので参考文献を読みました。

参考

ffmpeg で /dev/video0 からの静止画と動画を作成する

環境はUbuntuです。

ffmpegをインストール

sudo apt install ffmpeg

静止画の撮影

ffmpeg -f video4linux2 -s 640x480 -i /dev/video0 -vframes 1 ./test.jpg

動画の撮影

ffmpeg -f video4linux2 -s 640x480 -i /dev/video0 out.mpg

おわり

次回は動画をリアルタイムで配信できるようにしてみます。以下参考にしました。

TypeScript + Electronでアプリを作る

Electronを使う機会があったのでHello Worldまでを。まずは依存関係を入れて

yarn init
yarn add electron parcel

ファイル構成はこんな感じにし

$ tree -I 'node_modules|dist|.cache'
.
├── package.json
├── src
│   └── index.ts
├── web
│   ├── index.html
└── yarn.lock

スクリプトはこんな感じ

import electron from 'electron';

var main;

let createWindow = () => {
  main = new electron.BrowserWindow({ titleBarStyle: 'hidden', width: 800, height: 600 });
  main.loadURL('file://' + __dirname + '/index.html');
  main.on("closed", () => { main = null; });
}

electron.app.on('window-all-closed', () => {
  if (process.platform != 'darwin') {
    electron.app.quit();
  }
});

electron.app.on('ready', createWindow);

electron.app.on("activate", () => {
  if (main === null) {
    createWindow();
  }
});

HTMLはこんな感じ

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>hello, world</title>
  </head>
  <body>hello world</body>
</html>

ビルドをします

yarn run parcel build src/index.ts --out-dir ./web -t electron

起動します

yarn run electron ./web/index.js 

するとウィンドウが開くと思います。main.loadURL でローカルのファイルを指定しているわけですが、どうやらHTMLをコード上から渡すことはできず、どうしてもやりたいなら dataURL で送ればいけるんですって。HTMLファイルを設置しなくても、NodeからWebサーバーを別で起動してそこにリクエストを送らせればいいわけですが。

参考

Webデザインをする時によく使う色見本サイトFLAT UI COLORS 2

https://flatuicolors.com/

カラーコードが取得できるので、イメージを掴むのに使えます。私は心が腐っているのでさ、なんちゃってデザインをしていると、どんどん溝色になっていくので、このカラーパレットを見て心をフラットにしています。

なんだか先日私がこのサイトから色を取ってきてごちゃごちゃ作業してるのを後ろから見て便利!って言ってたスパイがいたので紹介しておきます。

Parcelの -t オプションでランタイム環境を指定する

parce build のオプション -t でランタイム環境が指定できます。

set the runtime environment, either "node", "browser" or "electron". defaults to "browser"

デフォルトではブラウザになっていて、electronアプリを作る時は electron を指定、nodeの時は node と指定するとか。そういえばparcelでビルドする時Webアプリケーションを作る時しかやったことなくて、nodeの時は ts-node コマンドを使っていたから気づかなかった。

試しにelectronアプリをTypeScriptで書いてビルドしてみたら

TypeError: fs.existsSync is not a function

と言われて起動できませんでした。