一身上の都合

プログラミングとかの話

ブラックフライデーで買ったもの

ブラックフライデーで買ったもののレビューです。

LG 55型 4Kチューナー内蔵 有機EL テレビ OLED55C2PJA Alexa 搭載 2022 年モデル 黒

リビングに置くのを大型モニターにするかテレビにするか迷いに迷って、結局テレビにした。
ちょうどAmazon でLG の22年エントリーモデルであるLG テレビ 55型 4Kチューナー内蔵 有機EL OLED55A2PJA スマートテレビ Alexa 搭載 2022 年モデルが10万円を切っていたのでそちらにしようかと思い現物を見に量販店に行ったところ、
LG の店員さんからこのA のシリーズよりも今回購入したC のシリーズの方が価格に見合うよと教えてもらった。 色と音と映像エンジンのことを考えて、C シリーズにすることを決めたのは良いものの、
量販店には23 年モデルしか置いておらず、セールで18万くらい(元値が30万だということを考えると大特価なんだろうけど)。
流石に予算オーバーかなと思い、性能もそこまで大差なさそうな22年モデルを買うに至った。

届いて早速いろいろ観てみたが音も映像も今のところ満足している。

EQUALS イコールズ テレビ台 壁寄せテレビスタンド WALL V2 ロータイプ (2020モデル) 棚板レギュラーサイズセット 32型〜60型対応 サテンブラック (棚板:サテンブラック)

元々狙っていたテレビスタンドが棚板セットでだいぶ安くなっていたので即ポチった。 似たような製品はあるが、取付可能重量と、あと一応耐震性も考えて選んだ。

今のところいい感じ。

アイ・エス 電子メモパッド 8.5インチ 書き消し可能 ホワイト IDM02-8-WH

iPad Pro を買おうと思ってるけど、とりあえずメモできるものがすぐに欲しかったので買ってみた。
電池が切れると消せなくなるみたいだが、コイン型電池を交換すればまた使えるらしい。
767 円なのでロクに使えなくてもしかたないと思っていたけど、以外に悪くない。
ペンの太さが筆圧依存っぽいのがちょっと使いにくいが、簡単な落書きには置いといても良い。

あとはティファールの深型フライパンを買ったたくらいだが、これはまだ届いていないので割愛。

余談だけど去年のブラックフライデーで買った曲面モニタを買い足そうかと見に行ったら、
買ったときより1,000 円くらい下がってた。 おすすめ。

fvm(flutter version management)で困ること

以下の環境はWindows11, WSL2 ですが、 macOS Ventura でも同様でした。

flutter commands から色が消える

通常flutter doctor を実行すれば次のように色のついた状態で内容が表示されると思う。

だがこれをfvm 経由で実行すると色が表示されない。

調べたところfvm のissue で次のようなコメントが見つかった。

引用すると、

I did some digging and it looks like all coloring done by flutter (ie. not pub, since it is external) passes through this method: https://github.com/flutter/flutter/blob/abecef6ed36565d5d756da3d406555a4e6e70387/packages/flutter_tools/lib/src/base/terminal.dart#L249

Which decides whether to color or not based on this:

https://github.com/flutter/flutter/blob/abecef6ed36565d5d756da3d406555a4e6e70387/packages/flutter_tools/lib/src/base/terminal.dart#L190-L191

However _platform does not seem to have a way to be overridden. To overcome it you can just replace the getter to always return true and recompile flutter locally:

ということらしい。具体的なワークアラウンドについてもshilangyu さんがスクショを貼ってくれているが、一応自分の方でも書いておく。
※以下は自己責任でお願いします。以下の内容により生じたあらゆる不利益または損害に対して、一切の責任を負いません。

  1. ~/fvm/default/packages/flutter_tools/lib/src/base/terminal.dartを変更
@override
bool get supportsColor => true;
// bool get supportsColor => _platform.stdoutSupportsAnsi;
  1. rm -dfr ~/fvm/default/bin/cache を実行

これで再びfvm flutter doctorを実行すればOK。 OKですね。

shilangyu さんに感謝です。

未解決: fvm flutter run でインタラクティブにデバイス選択ができない

flutter run を実行するとデバイス選択がシェル上でインタラクティブに可能なのだが、fvm を通すと以下のようにdeviceId を指定しろと言われる。

More than one device connected; please specify a device with the '-d <deviceId>' flag, or use '-d all' to act on all devices.

これについてもissue が見つかった。 wontfix タグは削除されているものの、まだ対応はされていない。

職場ではスクリプトを用意してくれた人がいるので従来通りっぽく動かせるのだが、pure なコマンドに比べるといくらか処理速度が遅いのが気になる。 fvm さん対応お願いします。

YouTube Data API で登録済みチャンネルの中からライブ配信中のものだけ取得しようとしたがQuota の上限に引っかかった

YouTube 配信開始の通知はGoogle アカウントへのメールか、スマホへのポップアップ通知しかないので、自分でAPI 叩いてDiscord とかに通知飛ばせるようにするかと思いちょっとしたツールを作りました。

が、一つ問題がありGCPYouTube Data API は一日10,000 Queries というQuota(割当)上限が決められており、さらに使用するAPI によってQueries の使用量が定められています。
Quota については公式のドキュメントYouTube Data API (v3) - Quota Calculator  |  Google Developers をご確認ください。

例を挙げると、
チャンネル登録に関するAPI であるsubscriptions.list を使用する場合はcost は "1" ですが、
動画を検索するsearch.list を使用する場合はcost は "50" も必要です。

今回やりたかったことは流れとして、

  1. 自分の登録チャンネルのID を取得する
  2. 各チャンネルの配信中の配信があればそれを返す
  3. それをDiscord とかで5分おき(配信開始は大抵キリの良い時間なので)に通知する

って感じなんですが、YouTube Data API では配信中かどうかの情報は videos または search リソースでしか取得できません。
videos に関してはChannel ID からは取得できず、search リソースを使用するしかないのですが、
登録チャンネルが50だった場合、search のコスト 50 × 50 で2,500 Queries を消費してしまうので課金する他方法がないようです。
Quota 上限の開放に関しては(個人だと難しいみたい)https://stackoverflow.com/questions/61281991/applying-for-additional-quota-for-youtube-api-as-an-individual-without-business/62686472#62686472なので、白旗です。

一応作ったものはこちら

github.com

Vue CLI でGoogleAppsScript アプリ を作成するまで

VueCLI4 でGoogleAppsScript アプリを作成する

GoogleAppsScript (以下GAS) で簡易なWeb サイトやアプリケーションが作成できるのですが、
それをVueCLI を用いて作成してみました。

Vue CLI のインストール

Vue.js のアプリケーションを簡単に作るためのCLI ツールであるVue CLI をインストールします。
Vue CLI はglobal install する必要があるので注意。

なおnpm を使用する場合は適宜読み替えてください。

$ yarn global add @vue/cli @vue/cli-init
yarn global v1.22.10
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Installed "@vue/cli@4.5.11" with binaries:
      - vue
✨  Done in 197.86s.

$ vue --version
@vue/cli 4.5.11
  • vue が動かない場合はグローバルインストールしたパッケージへのパスが通っていないと思われます。必要に応じてググってみてください。

プロジェクトを作成

プロジェクト内にすべてのソースコードが入ります。

$ vue create <appname>
* ここではappname は"vue-gas-app" とします。
** おそらくself singed certificate に関するエラーが生じるので、Global Protect を一時的に切断しましょう。
*** 終了後再接続するのを忘れずに。

実行後、以下の初期設定用インタラクティブモードに入ります。
今回は試しにManual で設定してみましょう。

Vue CLI v4.5.11
? Please pick a preset: (Use arrow keys)
  Default ([Vue 2] babel, eslint)
  Default (Vue 3 Preview) ([Vue 3] babel, eslint)
❯Manually select features
? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ Choose Vue version
 ◉ Babel
 ◯ TypeScript
 ◯ Progressive Web App (PWA) Support
 ◯ Router
 ◯ Vuex
 ◯ CSS Pre-processors
 ◉ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing
? Choose a version of Vue.js that you want to start the project with
❯ 2.x
  3.x (Preview)
? Pick a linter / formatter config:
  ESLint with error prevention only
  ESLint + Airbnb config
  ESLint + Standard config
❯ ESLint + Prettier
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ Lint on save
 ◯ Lint and fix on commit
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
❯ In dedicated config files
  In package.json
? Save this as a preset for future projects? (y/N) n
? Pick the package manager to use when installing dependencies: (Use arrow keys)
❯ Use Yarn
  Use NPM
✨  Creating project in /Users/user/work/vue-gas-app.
🗃  Initializing git repository...
⚙️  Installing CLI plugins. This might take a while...

yarn install v1.22.10
info No lockfile found.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
✨  Done in 123.97s.
🚀  Invoking generators...
📦  Installing additional dependencies...

yarn install v1.22.10
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...

success Saved lockfile.
✨  Done in 20.69s.
⚓  Running completion hooks...

📄  Generating README.md...

🎉  Successfully created project vue-gas-app.
👉  Get started with the following commands:

 $ cd vue-gas-app
 $ yarn serve

今回はVueCLI でデフォルトのビューのみのアプリを作成するので、Vue Router やVuex は使用しないものとします。
パッケージのインストールが完了したら試しに一度動かしてみましょう。

$ cd vue-app-demo

$ yarn serve

yarn serve

GoogleAppsScript の用意

以下のリンクからGoogle Apps Script API を「オン」にしておきましょう。
https://script.google.com/u/1/home/usersettings

GAS のソースコードはclasp というCUI ツールによってローカル環境と同期することができます。

$ yarn global add @google/clasp

$ clasp login

$ clasp create vue-gas-app
? Create which script?
  standalone
  docs
  sheets
  slides
  forms
❯ webapp
  api
Created new webapp script: https://script.google.com/d/<id>/edit
Warning: files in subfolder are not accounted for unless you set a '.claspignore' file.
Cloned 1 file.
└─ appsscript.json

ここで新たにappsscript.json と.clasp.json が作成されます。
最終的にGAS へはclasp push というコマンドでdist/ 内のファイルをアップロードするのですが、
dist/ 内にappsscript.json やCode.js を配置することを避けるために、gas/ というディレクトリを作成しましょう。

$ mkdir gas

$ mv appsscript.json gas/

$ echo .clasp.json >> .gitignore

またgas/ 内にGAS のエントリポイントとなるCode.js を作成します。

# Code.js
function doGet() {
  return getHtml()
}
function getHtml() {
  const html = HtmlService.createTemplateFromFile('index')
  return html
    .evaluate()
    .setTitle('vue-gas-app')
    .addMetaTag('viewport', 'width=device-width, initial-scale=1')
}

dist/ 内のファイルをGAS へpush するために.clasp.json を以下のように修正します。

{
  "scriptId":"<id>",
  "rootDir": "dist"
}

ビルドの設定

作成したgas/ 内のファイルをビルドの際にdist/ にコピーしてくれるように、webpack の設定をします。
VueCLI では従来のようにwebpack.config.js に設定するのではなく、vue.config.js 内に記述します。

# vue.config.js
const CopyWebpackPlugin = require('copy-webpack-plugin')

module.exports = {
  configureWebpack: {
    plugins: [
      new CopyWebpackPlugin([
        {
          from: path.resolve(__dirname, './gas'),
          ignore: ['.*']
        }
      ])
    ]
  }
};

また、VueCLI の通常のバンドルではGAS では読み込めない場合があるため、すべてをインラインでバンドルすることにします。

# vue.config.js
const path = require('path')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin')

module.exports = {
  publicPath: '/public',
  chainWebpack: config => {
    config
      .plugin('html')
      .tap(args => {
        args[0].template = './public/index.html'
        args[0].inlineSource = '.(vue|js|css)'
        return args
      })
  },
  configureWebpack: {
    plugins: [
      new HtmlWebpackInlineSourcePlugin(),
      new CopyWebpackPlugin([
        {
          from: path.resolve(__dirname, './gas'),
          ignore: ['.*']
        }
      ])
    ]
  }
};

deploy

では実際にビルドしてみましょう。

$ yarn build

ビルドしたものをclasp push でデプロイします。
また、不要なファイルがアップロードされないように事前に.claspignore を設定します。

/* .claspignore */
**/**
static/**
static/css/**
!appsscript.json
!Code.js
!index.html
$ clasp push

これでGAS の画面からデプロイすればOKです。

Appendix

Linter とFormatter

Linting rules に関しては好みが分かれますが、ここでは標準的に使用されているPrettier をフォーマッタに使用します。
VueCLI を使用してESLint + Prettier をインストールすると、自動的にESLint とPrettier で競合するルールをオフにしてくれるeslint-config-prettier がインストールされるので、基本的には自分で特にルールをいじる必要はありません。
私の場合は .prettierrc.js にてシングルクォートのみ有効にしてあります。

# .prettierrc.js
module.exports = {
  singleQuote: true,
};

【2020年8月版】NHK解約してみた

この度ついにNHKを解約した。
意外とすんなりいったので流れを書いておこうと思う。

なお、私はもともと地上波契約をしておらず、今回テレビを処分し受信できる設備が無くなったので解約したのであり、
そうでなくてNHKの料金を払いたくないだけという人はお引取りください。
見てるなら払え。

  1. テレビを売却
    10年ものの32インチテレビだったので引き取り手に苦労した。
    無償引取でもいいので出張対応してくれる業者を探し、引き取っていただいた。
    NHK解約には買取証明のようなものが必要と聞いたので、業者の方とメールでやり取りする際に領収書や明細が発行できるか尋ねたところ、 「買取証明書発行しますよ」とのことだったのでお願いした。
    おそらく同じようなことをよく言われるんだろうな。
    ちなみにテレビは家電リサイクル法の関係で、処分しようと思うと諸々5000円程度かかるのが辛い。

  2. NHKに連絡
    こちらに記載されているNHKふれあいセンターに電話をかけた。
    はじめはナビダイヤルのガイドに従い番号を入力していき、お決まりの「ただいま電話が大変込み合っております」のアナウンス。
    まぁ解約は往々にしてそうだよなと思いつつ待つこと1 分半、担当者の方に繋がった。
    「〇〇と申します。お世話になっております。この度テレビを処分したので、解約の申請書を頂きたいのですが。」と伝えたところ、
    「他に受信機はありませんか?」「テレビ売却の証明になるものはありますか?」などの質問を受けたあと、本人確認をされ、1 週間から10 日ほど解約の届出書が届くので、売却の証明になるものと合わせて送るよう説明いただいた。
    なお、本人確認の際に契約番号がわからなければ電話番号や住所から確認が行われるが、この際住所変更をしていないと手間になるので注意。
    実際今回事前に住所変更を行っておいたが、ネットで24時間受付しているので簡単だった(反映まで少し時間がかかる模様)。

  3. 解約届出書送付
    必要事項を記入して売却証明書と合わせて返送。
    解約処理が届いた時点から日割りで計算して過払い分は返金するとか電話口で聞いた。

以上。
NHKといえばアポもなくしつこく訪問してくるようなイメージしかなかったが、準備をして正当な理由を持って誠実な対応をすればなんの問題も無かった。

PCの冷却

会社から貸与されているノートPCがアホほど熱くなってすぐにカクついて、日ごろからストレスがマッハだったが、
この度とうとうブルースクリーンをジャンジャンバリバリ連チャンで出すようになったのでPCを冷却する何かを探し求めて密林へと旅立った。

結果的に購入したのがこちらである。

今のところ熱暴走は無くなった。安いから正直(安物買いの銭失いになるかな......)と不安だったけど、杞憂に終わりそう。

会計クイズの本

大手町のランダムウォーカーさんの会計クイズの本を漸く読みました。
(即買ったのに積んでた)

amzn.to

やっぱり会計クイズは最高のコンテンツだと思う。
ほどよく頭を使うし、社会人として知っておくべき知識も身につく。

本では普段のクイズではあまり触れられない、回答にたどり着くまでのロジックやアプローチもキャラクターの会話形式で示されているので初心者におすすめ。
簿記3級程度の知識は持っていたほうがより楽しめると思う。
というか個人的には社会人はみんな簿記を3級でもいいから勉強しておくべきだと思う。

Twitterを当初から拝見している身としては、昔見たことある問題が多いのがちょっと残念ではあったが、
間違えた問題もあったので良い復習になった。

まだ会計クイズに触れたことのない人は必読の一冊。