unhurried

コンピュータ関連ネタがほとんど、ときどき趣味も…

Angular 5 + Bootstrap 3でElectronアプリ開発

ElectronでAngular 5とBootstrap 3を使う方法をまとめました。ng-bootstrapngx-bootstrapはAngular 5には対応していないため、Bootstrap 3を動かすためにjQueryを使っています。

  • Electronをインストールする。
npm -g install electron
  • Electron用のプロジェクトを新規作成する。
npm init -y
{
  ...
  "main": "main.js",
  ...
}
  • main.js ではこの後に作成するAngularプロジェクトのビルドで生成されるindex.htmlを参照するように設定する。
'use strict';

const { app, BrowserWindow, protocol } = require('electron');
const path = require('path');
const url = require('url');

var mainWindow = null;

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

app.on('ready', function() {
  mainWindow = new BrowserWindow({ width: 800, height: 600 });
  mainWindow.loadURL('file://' + __dirname + '/angular/dist/index.html');

  mainWindow.webContents.openDevTools();

  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});
  • Angular用のプロジェクトを作成してBootstrapとjQueryをインストールする。
npm install -g @angular/cli@latest
ng new angular
cd angular
npm install bootstrap --save
npm install jquery --save
npm install @types/jquery --save-dev
{
  ...
  "styles": [
    "../node_modules/bootstrap/dist/css/bootstrap.min.css",
    "styles.css"
  ],
  "scripts": [
    "../node_modules/jquery/dist/jquery.min.js",
    "../node_modules/bootstrap/dist/js/bootstrap.min.js"
  ],
  ...
}
  • angular/src/index.html にbaseパスを指定する。
    • baseパスを指定しない場合、Electronは相対パスをルートからの相対パスを解釈してしまうため。
...
<head>
  <base href="./">
...
  • Angularビルド後にelectronコマンドを実行するとアプリを起動できる。
ng build
electron ../
その他
  • Angular 5をangular-cliでインストールした状態ではnpm依存関係の警告が出ますが、これは今後のアップデートで解消されると思います。
my-app@0.0.0 C:\Users\tkykt\home\git\electron-angular-bootstrap
+-- UNMET PEER DEPENDENCY @angular/compiler@5.0.1
+-- UNMET PEER DEPENDENCY @angular/core@5.0.1
`-- bootstrap@3.3.7

npm WARN optional Skipping failed optional dependency /chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.1.3
npm WARN codelyzer@3.2.2 requires a peer of @angular/compiler@^2.3.1 || >=4.0.0-beta <5.0.0 but none was installed.
npm WARN codelyzer@3.2.2 requires a peer of @angular/core@^2.3.1 || >=4.0.0-beta <5.0.0 but none was installed.
参考

各銀行ATMでの硬貨預け入れ条件

私は普段は財布をポケットに入れているのであまり小銭を持ち歩きたくないのですが、現金でしか支払えないお店もあるので、どうしても小銭が溜まってしまうことがあります。そこで銀行のATMで簡単に硬貨を預け入れできないかと思い、各銀行(長野県内)の対応状況を調べてみました。

ゆうちょ銀行
  • 平日7:00~21:00 土日祝9:00~17:00
  • 一度の預け入れで計100枚まで
八十二銀行
みずほ銀行
三井住友銀行
  • 窓口に併設されたATMのみ

  • 平日8:45~18:00のみ

  • 一度の預け入れで計100枚まで

りそな銀行
  • 一部の店舗・機械のみ

  • 平日8:45~18:00のみ

長野ろうきん
  • 情報なし
長野銀行
  • 情報なし
松本信用金庫
  • 情報なし

SwaggerCodegenでAPIモックを作る

API仕様を定義するフォーマットとしてデファクトスタンダートとなりつつあるSwaggerを利用してAPIモックを作ろうとしたときにはまったところがありましたので、メモしておきます。

手順(Node.js)

(1) SwaggerCodegenをダウンロードする。

# Mavenリポジトリからjarファイルをダウンロードする。
wget http://central.maven.org/maven2/io/swagger/swagger-codegen-cli/2.2.3/swagger-codegen-cli-2.2.3.jar -O swagger-codegen-cli.jar
# helpを表示してみる。
java -jar swagger-codegen-cli.jar help

(2) Swaggerファイルからモック用のコードを生成する。

# -i Swaggerファイル
# -o 出力先ディレクトリ
java -jar swagger-codegen-cli-2.2.3.jar generate -i activation3.yaml -l nodejs-server -o nodejs
node nodejs\index.js
はまったところ
APIを呼び出したときに下記のエラーが出力される
Error: Cannot resolve the configured swagger-router handler: xxx
    at swaggerRouter ...
  • 私の場合の原因はコード生成時に変数名として利用される以下の項目にマルチバイト文字が使われていたためでした。
    • operationId
    • tags

参考

GoogleフォトがGoogleドライブに同期されないときの対処法

Googleフォトは画質設定を「高画質」にしていれば容量制限がないため、写真をたくさん取るけれども画質はそこそこで満足という方に適したサービスです。私はGoogleフォトとGoogleドライブの同期機能を使ってGoogleドライブにフォルダを作って写真を整理しています。ところがこの同期機能が厄介で、一部の写真がいつまで待っても同期されないという現象がときどき発生します。私の経験則では、このような場合には下記の手順で対応するのが良いです。

  • Googleフォトの写真を削除する(ゴミ箱に入れる)。
    • 正常に同期されている写真もまとめて削除しても問題ありません。
    • 正常に同期されている写真はGoogleドライブからも削除されます。
  • Googleフォトのゴミ箱から写真を復元する。
    • 多くの場合はこれでGoogleドライブに同期されていなかった写真が同期されます。
    • 正常に同期されていた写真はGoogleドライブでも同じフォルダに復元されます。
  • それでも同期されない場合は一度Googleフォトから完全に削除して再度アップロードする。
    • このときは正常に同期されている写真は対象から外した方が良いです。(Googleドライブの同じフォルダに復元することができないため。)

参考

アメリカから日本への郵便転送

アメリカから日本に帰国する際の行った諸々の手続きについてまとめています。今回は郵便の転送手続きについてご紹介します。

アメリカから日本への郵便転送

  • アメリカから日本へ帰国する場合、アパートや家を退去する前の2週間前にUSPSへ転送依頼ができる。
  • オンラインで申請する方法($1)とPS Form 3575という申請書に記載して郵送で申請する方法がある。
    • PS Form 3575は郵便局でもらえて切手は不要なため、こちらの方法は無料で手続きができる。
  • アメリカ国外へ転送する場合はオンラインではできず、申請書を利用する必要がある。
    • ただし、申請書の転居先欄もアメリカ仕様になっているため、州(State)欄に「TOKYO, JAPAN」のように、また郵便番号も5桁のところに7桁を無理やり書き込む必要がある。
  • 申請書提出後は5営業日以内に転居前の住所に転居確認通知書(Move Validation Letter) が届く。
  • 依頼した転送処理は12ヵ月間有効となる。
参考

NOSQL DATA MODELING TECHNIQUES 要約

NoSQLについて多くの書籍や記事がありますが、実際にアプリケーションのバックエンドとして使うときに必要となる知識についてはあまり紹介されていないように思います。内容が少し抽象的ではありますが、NOSQL DATA MODELING TECHNIQUESというNoSQLでのデータモデルに関する記事を見つけたので、要約をしてみました。

概説
  • SQLとリレーショナルデータモデルはかなり昔に設計され、データベース内のデータ集計処理や並列実行性・一貫性・データ型検証に重きを置いていた。ところが、アプリケーションにはデータ集計をしなく、それなりに一貫性なども担保できるものが多くある。
  • データ集計処理、並列実行性・一貫性・データ型検証を省くことで、パフォーマンスとスケーラビリティを大幅に向上でき、これにより生まれたのがNoSQLデータベースである。
  • データモデルの進化
    • Key-Value → Ordered Key-Value → Big Table → Document (+ Full Text Search)
    • GraphデータベースはOrdered Key-Valueから派生した亜種と見なせる。
NoSQLでのデータモデル化に関する一般的な注釈
  • リレーショナルデータモデルはデータ中心にモデル化することに対して、NoSQLデータモデルはアプリケーションにアクセスパターン中心にモデル化を行う。
  • NoSQLデータモデルにはリレーショナルデータモデルよりも多くのデータ構造とアルゴリズムに関する理解が必要となる。
抽象的なテクニック

(1) 非正規化

  • データの複製を複数の場所に置くことで、全体のデータ量が増える欠点があるものの、クエリ時にアクセスするデータ量が減り、クエリの処理を単純にでき、高速化ができる。

(2) 集約

  • NoSQLは柔軟なスキーマを持つため、多対多のリレーションをドキュメントを入れ子にすることで表現したり、異なる属性を持つレコードも1つのテーブルに集約することができる。

(3) アプリケーションでの結合処理

  • NoSQLではテーブル結合処理はめったにサポートされていなく、更新が多いデータには非正規化や集約による結合処理の実現が適さない。
  • この場合は、アプリケーションでクエリ時に結合処理を行うことが適する。
一般的なモデル化テクニック

(4) アトミックな処理を行うための集約

  • NoSQLデータベースではトランザクションのサポートは限定的であるが、アトミックな処理を行う必要があるデータを1レコードに集約することで一括で更新が可能となる。

(5) 順序を持つキー

  • NoSQLデータベースには連続したIDを生成する機能を提供しているものがあり、この機能を利用することでレコードに順序を設定することができる。

(6) 次元削除

  • Geohashのような次元削減アルゴリズムを使い多次元データを1次元のカラムに格納する。

(7) インデックステーブル

  • インデックスをサポートしないシステムでは、検索対象カラム→IDというテーブルを作ることでインデックスを実現できる。
  • ただしデータ更新時にアクセスする必要があるテーブルが多くなり、一貫性の問題が発生する。

(8) 複合キーによるインデックス

  • 複数のキーを結合してインデックステーブルを作ることで、例えば2つのキーを結合した場合、1つ目のキーでの検索と、1つ目のキーと2つ目のキーでの検索ができる。

(9) 複合キーでの集約

  • 複合キーをレコードのグループ化に使うことで、グループに属するデータをインデックスを使って取得してデータを集約するという処理を実現できる。

(10) インデックスでの検索と全件探索による集約

  • データモデルというよりはデータ処理に関するパターン
  • あるカテゴリに含まれるレコードの属性を集約したいときに、インデックスを使ってレコードのIDの集合を検索した後に、そのIDの集合に対して全件探索を行う。
階層構造をモデル化するテクニック

(11) 木構造の集約

  • 木構造JSON形式などで非正規化して1レコードに格納する。
  • 木構造全体を一度で取得することは容易だが、更新や検索のコストは高い。

(12) 隣接リスト

  • グラフ構造の各ノードを隣接するノードのIDと共に1レコードに格納する。
  • 隣接ノードによるノードの検索はし易いが、大規模のグラフの探索は効率が悪い。

(13) マテリアライズド・パス

  • 木構造などで各ノードのレコードにその親子ノードを含め非正規化して格納する。
  • 木構造の一部を探索なしに取得でき、階層的なカテゴリを持つアイテムなどへの全文検索を行いたいときに便利である。

(14) 入れ子集合モデル

  • 木構造などの入れ子になっている集合データをSQLデータベースで扱うためのテクニックであるが、NoSQLにも適用できる。
  • リーフノードを配列にして格納し、ブランチノードについてリスト中の開始・終了位置のインデックスを作成する。
  • あるノードの子ノードをグラフ探索なしにできるが、更新コストが高いため静的なデータに向く。

(15) 入れ子構造の平坦化:フィールド名に数字を付ける

  • 同じフィールド名のドキュメントを入れ子にするドキュメントを1つのドキュメントに平坦化するために、フィールド名に数字を付け加える。
  • 入れ子にしているドキュメントが多い場合はフィールドでの検索条件が複雑になる。

(16) 入れ子構造の平坦化:近接クエリ

  • 同じフィールド名の子ドキュメントの値を連結することで1つのフィールドにまとめる。
  • 連結した文字列で検索することでシンプルな条件式にできる。

(17) グラフのバッチ処理

  • グラフデータベースは少数のノードへのアクセスには優れるがグラフ全体に対する処理にはスケールしない。
  • NoSQLにグラフを格納してMapReduceアルゴリズムを適用することで大規模なグラフに対する処理をスケールさせることができる。

IPv6の基本

IPv4のアドレス数不足を解消するために策定されたIPv6ですが、あまり使う機会がなかったためよく理解していませんでした。今回は基本的な仕様を整理してみました。

IPパケットの変更点

  • アドレス領域:32ビット→128ビット
  • ヘッダ:IPv4であまり使用されていなかった項目が廃止・オプションとなった。

アドレス表示記法

  • 16ビットごとに8ブロックに区切り、各ブロックを16進法で表記して「:」で連結する。
  • ブロック内の先頭から連続する0は省略できる。
  • 連続する全て0のブロックは1つだけ「::」で置き換えられる。
  • 例:1234:56::7890:abcd:ef

グローバル・ユニキャスト・アドレス割り当て

  • 形式:ISP識別部(32) ISPユーザー識別部(x) サブネットID(32-x) インターフェイスID(64)

  • サブネットID:ローカルネットワークの識別に使う。

  • ISP識別部 ISPユーザー識別部はグローバル・ルーティング・プレフィックスと呼ばれ、ISPから割り当てられるネットワークの識別子となる。

  • インターフェイスIDは各ホストで生成でき、MACアドレスから生成する方法(EUI-64)とランダムに生成する方法(RFC4941)がある。(DHCPv6や手動で設定することもできる。)

特別なアドレス

  • リンクローカル・ユニキャスト・アドレス

    • 形式:fe80::インターフェースID
    • サブネット内のIPv6制御に使う。
      • 例:ホストが最初にゲートウェイへサブネット・プレフィックスを問い合わせるときの送信元アドレスとして使う。
  • マルチキャストアドレス

    • 形式:ffで始まるアドレス

    • グループIDを指定して特定のグループ内にマルチキャストするためのアドレス。

    • IPv4でのブロードキャストを置き換える。
  • エニーキャストアドレス

    • 複数のノードに同一のアドレスを割り当てることができる。
    • エニーキャストアドレス宛てに送信されたパケットはルーティングプロトコル上最も近いノードに送信される。

IPv4との共存方法