僕は発展途上技術者

CSV形式のオープンデータをブラウザの地図上でかんたんに確認できるglnmapsというツールを作りました

AEDの設置場所や避難場所などのデータを各自治体が積極的に公開するようになってきました。これらはオープンデータと呼ばれており多くはCSVファイルでダウンロードできます。こうしたデータをサクッとローカル環境で確認したいなと思っていたので、ローカル環境で無料で使えるGeolonia Maps上にかんたんに表示できるツールを作ってみました。

» https://github.com/champierre/glnmaps

各プラットフォームで動くバイナリを用意できるよう、Denoで開発しました。

glnmaps(Geo*LoN*ia Maps) とは?

glnmaps(GeoLoNia Maps)は、各自治体が公開しているCSV形式のオープンデータをブラウザの地図上で確認できるツールです。 技術的な知識がなくても、誰でも簡単に使える平易なツールをめざしています。 ソースは1個のHTMLファイルとしてダウンロードできるので、それをホスティングして公開することも簡単です。

使用しているGeolonia Mapsは、https://.test 及び、http://127.0.0.1:<ポート番号> や http://localhost:<ポート番号> などのローカル環境で使用した場合や、GitHub Pages(https://.github.io)上では無料で使用できるので、開発やオープンソースのプロジェクトで利用することができます。

参考: Geolonia Mapsの開発環境での利用について

使い方

1. オープンデータとして公開されているCSVファイルを用意

各自治体のホームページなどで公開されているオープンデータのCSVファイルをダウンロードします。データカタログ横断検索システムで探すのも用意でしょう。

サンプルとして東京都調布市が公開している公共施設のデータセットを用意しておきました。

東京都 調布市 公共施設 データセット

※ オープンデータを管理するにはdimを使うと便利です。サンプルのdim.jsonをダウンロードして、

dim install

と実行すれば上記サンプルを含めたデータセットを簡単に用意できます。

参考: そろそろオープンデータを無秩序に管理するのは卒業したいので📦データを管理するパッケージマネージャを開発した【ツール開発】

2. glnmapsを使って地図に表示

glnmaps <CSVファイルのパス>

を実行するだけです。

glnmaps is running. Access it at: http://localhost:3000/

というメッセージが表示されたら、ブラウザを開き http://localhost:3000/ にアクセスしてください。

glnmaps.gif

3. ソースをダウンロード

「ソースをダウンロード」のリンクをクリックすると、ソースのファイル(index.html)をダウンロードすることができます。

Chromeの拡張機能「Web Server for Chrome」などを使い、ローカルのWebサーバーでアクセスできるようにしたり、ホスティングサーバーに配置して公開することもできます。

web_server_for_chrome.gif

インストール

1. glnmapsのバイナリをダウンロード

aarch64-apple-darwin

curl -L https://champierre.github.io/glnmaps/binaries/aarch64-apple-darwin-glnmaps -o /usr/local/bin/glnmaps

x86_64-apple-darwin

curl -L https://champierre.github.io/glnmaps/binaries/x86_64-apple-darwin-glnmaps -o /usr/local/bin/glnmaps

x86_64-pc-windows-msvc

curl -L https://champierre.github.io/glnmaps/binaries/x86_64-pc-windows-msvc-glnmaps -o /usr/local/bin/glnmaps

x86_64-unknown-linux-gnu

curl -L https://champierre.github.io/glnmaps/binaries/x86_64-unknown-linux-gnu-glnmaps -o /usr/local/bin/glnmaps

2. 実行できるようにアクセス権を変更

chmod a+x /usr/local/bin/glmaps

20歳の自分に人生のアドバイスができるとしたら、どんなメッセージを送りますか?

友人からこんな依頼を受けました。

20歳の自分に人生のアドバイスができるとしたら、どんなメッセージを送りますか?

という質問に答えてくれ、と。

キャリアコンサルティング論の講義のために参考にしたいということなので、想定されている回答とは違いそうなのだが、まっさきに頭に思い浮かんだのは、

若いときに、将来の自分から借金してでも、モノとかではなく体験とかにもっとお金を使うべきだった

ということ。ちょうど2月くらいに以下のように思ったのでした。

詳しくは、将来の自分は今より稼いでいるという想定で、若いときには体験にお金をもっと使うべきと主張する、下記の DIE WITH ZERO という本に書いてあります。

PoseNet2Scratch を使っていつでもどこでも「キラーン!」と賢くなる

MakerFaire 2020 ではやっていた「キラーン!」シール。

↓「キラーン!」シールについて知らない方はこちら

メイカーフェアで来場者を賢くした :: デイリーポータルZ

僕はもらいそびれてしまって悔しかったので、身体の各部分の座標を取得できるScratchの拡張機能 PoseNet2Scratch を使って作ってみました。これでどこでもいつでも賢くなれます。RubyKaigi に向かう途中、作ったので新幹線の中でキラーン!

この機会に PoseNet2Scratch を Xcratch に対応させたので、以下のリンク先より、誰でも賢くなれます。キラーンのサイズや位置は適宜直してください。

↓リンク先をクリックしたら、緑の旗ボタンを押してください。

https://xcratch.github.io/editor/#https://champierre.github.io/posenet2scratch/kashikokunaru.sb3

「統一教会」や「原理」といえば、思い出す大学生のときの思い出

この話は妻には笑い話として、こども達にはこういうのには気をつけないといけないよという警告として何度か話したことはあるのだが、当時は「そんなのに騙されるの馬鹿だなあ」と言われそうなのが嫌だったみたいな感覚があって親にも友達にも相談することがなかった。

1991年3月、入学手続きのための書類を手に僕は井の頭線駒場東大前の駅を降りた。一通りの手続きを終えると、サークルや各種運動部の勧誘を受ける中、今でははっきり覚えていないのだけれど、確か二人組の男性の学生に声をかけられた。曰く「僕らのサークルは人生の目的を探求するサークルで一度話を聞いてみないか、うんぬん」といった内容で、いま思うとどうしてこんな話にひっかかってしまったのか本当にわからないのだけれど、なぜか好奇心からかその人達について行ってしまった。駒場東大前の駅前の商店街のなかの小さな雑居ビルの、たしか階段をあがっていった2階かなんかのやや広めの部屋に連れて行かれ、そこで20人くらいだか僕と同じ新入生の学生が集められていた。スーツを来た、学生なんだかそれよりやや年上の人が登場して、小一時間くらいなんだかありがたいようなそうでないような講釈を聞かされた。その講釈が終わったあと、サークルの新歓合宿があるからぜひ参加しないかと誘われるのだ。教養課程では、第2外国語でどの言語を取るかによって、40人くらいのクラスごとに分けられており、そのクラスの人たちの親睦を深めるためということで別に新歓合宿があることが決まっていて、その合宿の日程とかぶるから参加するのは無理だと僕は言うと、クラスの新歓合宿なんか参加してもあまり意味がない、ぜひそのサークルの合宿の方に参加すべきだとやや強く勧められたように思う。

原理研という統一教会系のサークルがあって、その勧誘をおこなう女子学生、いわゆる原理ギャルには気をつけるように、といった注意惹起を学内で聞くようになるのは、入学したあと4月になってから。同じクラスの学友からだったり、部活動の同期や先輩から聞くようになるのだが、3月のこの時点ではそうした情報はまだあまり耳にしていない段階だったのだ。クラスの新歓合宿に参加すれば、2年生の学生も何人か同行してくれていることもあって、そうした情報が入ることが予想されるので、それを阻止するためにサークルの方の合宿に参加させたかったのかな、と今では推察される。幸福の科学やらオウム真理教やら、当時はいろいろあって、各種団体がいろいろな形のサークルを隠れ蓑にしていたというから、そのサークルがいったいどこの組織に属するものだったかは今となってはわからない。ひょっとして本当に「人生の目的」を探求するためのサークルだったのかもしれない、いや、なさそうだけど。。 ともかく、僕は良くわからず合宿の前金だとかいう5000円を置いて帰り、しばらく一人自分で考えたあと、やっぱり怪しいけど、5000円取り戻しに行くのはリスクありそうだし、なんだか恥ずかしくて誰にも相談できず、そのサークルとはその後いっさい関わることはなかった。

限りなく怪しいが、断定はできない話ではあるのだけれど、「統一教会」というワードを聞くようになった最近、このときの思い出が鮮明に思い起こされる。

Rails 7アプリ on Heroku でPostGISを使い、外部APIを使わず緯度経度から県名を導く

PostGISを扱う練習として、HerokuでRails 7アプリからPostGISを使えるように設定し、緯度経度を与えたときに、その場所を含む県名を取得して表示するようなサービスを作ってみました。

DockerでRails 7アプリを動かす

第一歩として、ローカル環境でRails 7のアプリを動かします。Docker DesktopなどをインストールしていてDockerのセットアップが済んでいることが前提です。

ryanwi/rails7-on-docker

にあるコードをgit cloneし、READMEにある通り、セットアップをおこなって動かします。

http://localhost:3000 にアクセスすれば、以下のようにトップ画面が表示されます。

PostGISを有効にする

以下の3箇所を修正してローカルのDocker環境でPostGISを有効にします。

Gemfileに以下を追加します。

gem 'activerecord-postgis-adapter'

config/database.ymlのadapterをpostgisに変更します。

default: &default
  adapter: postgis

docker-compose.ymlでdbホストのイメージを変更します。

  db:
    image: mdillon/postgis

またPostGISを有効にするためのマイグレーションファイルを作成します。

docker-compose exec web rails g migration AddPostgisExtensionToDatabase

で生成したマイグレーションファイルの中身は

class AddPostgisExtensionToDatabase < ActiveRecord::Migration[7.0]
  def change
    enable_extension 'postgis'
  end
end

とします。

これらの変更をおこなった上で、再度docker-compose buildから環境の再構築をおこなうのですが、その前にdocker volume rmで、最初に作ってしまったデータベース用のdockerボリュームを削除しておきます。

docker volume rm rails7-on-docker_pg_data

これを行った上で、docker-compose buildから環境の再構築をおこないます。

再構築が終わり、再びdocker-compose upでコンテナを起動したら、

docker-compose exec db bash

の後、

psql -U postgres railsondocker_development

でpostgresに接続後、SELECT postgis_version(); を実行して、以下のようにpostgisのバージョン情報が出力されれば、PostGISの設定が有効となっています。

postgres=# SELECT postgis_version();
            postgis_version            
---------------------------------------
 2.5 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
(1 row)

Herokuで動かす

ここまでのコード変更は自分のGitHubリポジトリにコミット済みであることが前提で、Herokuで動かす手順は以下の通り。

GitHubリポジトリに接続し、

Automatic Deploysを有効にします。

config/database.ymlのproductionの部分を以下の通り書き換え、

production:
  <<: *default
  url: <%= ENV.fetch('DATABASE_URL', '').sub(/^postgres/, "postgis") %>

git pushすると、自動的にHerokuにデプロイされます。

最初、db:migrateが必要なので、

heroku run rails db:migrate -a <アプリ名>

を実行します。

heroku pg:psql -a <アプリ名>

でHerokuのDB(postgres)に接続し、ローカル環境のときと同様、SELECT postgis_version(); を実行して、PostGISの設定が有効となっていることを確認します。

緯度経度情報を保存するPointモデルを作成

緯度と経度、そして県名を保存できるPointモデルを操作するscaffoldを作成します。

docker-compose exec web rails g scaffold Point 'lat:decimal{10,2}' 'lng:decimal{10,2}' prefecture:string

migrationを実行します。

docker-compose exec web rails db:migrate 

県のポリゴンデータ

県のポリゴンデータを作成するための準備として市区町村のポリゴンデータをPostGISに取り込みます。

国土交通省の国土数値情報ダウンロードのページから「全国」のデータをダウンロードし解凍します。(令和3年のデータファイルはN03-20210101_GML.zip)

国土数値情報 | 行政区域データ

解凍したフォルダN03-20210101_GMLはアプリ直下のdbフォルダの下に置いておきます。

docker-compose.ymlを以下のように編集し、docker-compose buildで、コンテナを再構築し、上記フォルダにコンテナからアクセスできるようにしておきます。

  db:
    image: mdillon/postgis
    env_file:
      - .env/development/database
    volumes:
      - .:/usr/src/app <-- この行を追加
      - db_data:/var/lib/postgresql/data
docker-compose exec db bash

にdbホストに接続し、シェープファイルからSQLファイルを生成するためのコマンドshp2pgsqlを使って

shp2pgsql -c N03-20210101_GML\\N03-21_210101.shp shapes > shapes.sql

で全国の市区町村のポリゴンデータをPostGISに取り込むためのSQLファイルを作成します。

次に

psql -U postgres railsondocker_development < shapes.sql

を実行して、ポリゴンデータをshapesテーブルに取り込みます。

次に

psql -U postgres railsondocker_development

でpostgres接続後、

CREATE TABLE prefectures AS 
SELECT 
n03_001 AS pref_name,
ST_Multi(ST_Union(geom)) AS geom
FROM shapes
GROUP BY n03_001;

を実行して、各都道府県に属する市区町村のポリゴンデータを結合して、都道府県ごとのポリゴンデータをprefecturesテーブルに抽出します。

できあがったprefecturesテーブルをsqlファイルにエクスポートします。

pg_dump -U postgres --table prefectures railsondocker_development > prefectures.sql

Heroku 上では、このprefectures.sqlだけを読み込みます。

heroku pg:psql -a <アプリ名> < prefectures.sql

ポリゴンデータから緯度経度が所属する都道府県を導く

緯度、経度を入力し、Pointのデータを保存したときに、どの都道府県のポリゴンデータにその緯度・経度が含まれるかを調べ、その結果をprefectureにセットします。

以下の通り、Pointモデルのbefore_saveにその処理を定義します。

class Point < ApplicationRecord
  before_save :set_prefecture

  private
  def set_prefecture
    # 県名を取得
    res = ActiveRecord::Base.connection.select_all("SELECT pref_name FROM prefectures WHERE ST_Within(ST_GeomFromText('POINT(#{lng} #{lat})'), geom);")
    self.prefecture = res.first["pref_name"]
  end
end

Pointの入力フォームでprefectureを入力する必要はないので、その部分を削除します。

http://localhost:3000/points/new に削除し、たとえば以下のように緯度、経度を入力します。

Create Pointボタンをクリックすると、以下のようにその緯度、経度が属する都道府県が保存され、表示されます。

このとき、Geocodingなどの外部APIにアクセスしていないので、高速に検索できています。

参考リンク

Kaggle

Kaggleという機械学習のコンペのプラットフォームがある。留学中の長男がこのコンペの一つで順位が確定し、銅メダルを取ったとのこと。参加者3000超のうち、上位0.2%が金、5%が銀、10%が銅を獲得できるのだそうだ。犬や猫の写真が与えられ、どれだけ可愛く見えるか数値で表されたその人気度を機械学習で推測するプログラムを書くというのがコンペの内容。マレーシアにあるPetFinder.myという保護犬、保護猫と引き取ってくれる飼い主とをマッチングさせるサービスで、写真を掲載するときに使われることも目的としている(プログラムや使われた学習済モデルは公開されるので、上位のモデルは実際に使われるのかもしれない)。人間でやったら炎上しそうな内容ではあるが、保護猫、保護犬をできるだけ可愛くみせることで、引き取ってくれる飼い主をより多くマッチングさせることができるというわけだ。

機械学習には興味があるもののコンペに出られるほどの専門知識を僕は持ち合わせていないので、LINEで相談されてもろくなアドバイスを返せてはいなかったのだけれど、コンペ最終日まで毎日変わるリーダーボード上の息子の順位を一喜一憂しながら眺めるのはなかなか楽しい。リーダーボードというのは順位表で、最終日まではテストデータとして犬や猫の写真のたとえば25%というように一部しか与えられていない。それらの写真と人気度が与えられているので、写真やそのほかにも与えられた情報を元に人気度を導くアルゴリズムや機械学習モデルをうまく作り出す。そして、コンペ最終日を過ぎると、それまで公開されていなかった残りの本番用データ75%に対して適用し、その結果で最終順位が決まる。この仕組みがなかなか面白く、最後まで順位がわからなくてハラハラドキドキする。実際、最終日手前までは長男の順位は銀メダル圏内だったのだが、それは予選みたいなもので、あくまで最終結果だけがすべてだ。ツイートのなかで shake-down とあるのは、最終結果でそれまでの順位より下がることを意味する Kaggle 用語のようだ。逆に順位が上がることを shake-up というのだそうだ。shake-down したが、なんとか銅メダル圏内に残ったという形だ。さらに、最終日後しばらくの期間、不正があったかどうか(まったく同じプログラムが提出されていないかどうかなど)が調査されるらしく、数日経った今日、順位が確定したらしい。

ほかにも、参加は一人でもあるいはチームでもできるらしく、チームの場合は、たとえばそれぞれでモデルを作成し、予想した結果の平均を取ったり、多数決で決めた結果を採用するといったアンサンブルという手法があったりするのだそうだ。アルゴリズムやプログラムの詳しい内容はわからなくても、ロボコンや e-sports の競技を観戦、応援しているような楽しさがある。

長男が留学でシアトルに発ってから約2週間が経とうとしている

長男が留学でシアトルに発ってから約2週間が経とうとしている。

ブログシステムを Next.js で自作して、近況を報告してくれるようになったので、僕も思い出したようにこの自作ブログを久々に更新しようと思う。

心配する僕の家族(長男にとっては祖父母)にブログのリンクを送ったら、父親から、

約50年前に一人でアメリカ、メキシコ経由でミラノからペルージャに行き、下宿屋を探して苦労したことをついこの間のことのように思い出しました。

という感想が送られてきた。僕は1歳から約2歳までミラノで育ち、その後はパリで8歳になる少し前まで育ったのだが、初めて聞くエピソードだった。

僕も、約20年前、アメリカ、カリフォルニアに妻と引っ越すことになり、着いてすぐにソーシャルセキュリティオフィスでSSNを取得したり、Wells Fargo に行って約2時間もかかって銀行口座を開いてもらったりした苦労を思い出す。

でも、父の時代からももちろんそうだが、この20年でもおもにスマホとインターネットの力で格段に便利になっていることを痛感する。

出発前、Amazon ですでにアメリカのプリペイドのSIMカードを買っていたので、空港に着いたらすぐ SIM カード入れ替えて、無事到着の一報を LINE で受け取ることができる。

僕のときは、一晩かけて日本ではやっているらしい音楽を Napster などからダウンロードしてきて DVD に焼いていたりしたが、いまはストリーミングサービスで気軽に聴ける。

郊外に住んでいたので、1時間近くかけてサンフランシスコのジャパンセンターにある紀伊國屋書店まで行って、1.5倍から2倍近くする日本の本を購入していたりしたのだが、今は電子書籍を定価でいつでも購入することができる。

AAA(日本のJAFにあたるロードサービス)に入会すると、アメリカ中の地図を無料で取得できるということで、旅行で行く可能性もあるところも含め、住む場所近辺の地図などを取り寄せ、出かけるときにはいつもそれらの地図と Mapquest で道案内を調べてプリントアウトしたものが欠かせなかったのだが、いまでは Google Maps があればどこにでも行けるとのこと。

うらやましい。

とはいえ、やはり異国での生活というのは苦労の連続だ。これからたくさん苦労するのだろうなと思うと、心配でもあり頼もしくもあり、複雑な気分だ。

ファン歴30年の僕が選ぶデビュー30周年スピッツの曲ベスト10

スピッツのメジャー・デビューは1991年3月25日で、それまで大学の受験勉強にほぼすべてのリソースを振り向けていたあとに解放された僕の乾いた心にすっと入ってきたのがスピッツの曲だった。最初のアルバムの「スピッツ」と2枚目の「名前をつけてやる」は、楽器やバンドに興味を持っていた弟が買ってきたものだった。「このバンドが良い」とすすめてきて、僕もミニコンポが置いてあった弟の部屋でその2枚を良く聞いていたものだ。3枚目のアルバムの「惑星のかけら」は大学の生協だけに許される、発売日に10%引きで買った。卒業論文の執筆、研究で毎晩のように研究室で徹夜で過ごしていたときは、「ロビンソン」がヒットする前で、その当時まだほとんど知られていないスピッツのアルバムをヘビーローテーションでかけていたら、同じ研究室の同学年の仲間たちが気に入ってくれて、論文を書き上げたあとの打ち上げでカラオケに行ったときにはみんなでスピッツの曲を歌っていた。

僕は自分が好きだと思ったものは、ほぼだいたいそのままずっと好きのままでいることが多い。映画なら5歳のときに初めて観た「スター・ウォーズ」がずっと好きだ。スピッツは今年メジャー・デビュー30周年だそうで、ということは僕はファン歴30年だ。30年というのは今までの人生のほぼ3分の2にあたる。30年間、どの瞬間をとってもスピッツの曲を聞いていたので、スピッツの曲を聞くとそのときの自分を思い出す。

30周年を記念して、 スピッツデビュー30周年 みんなで作った!スペシャルプレイリスト - スピッツ が発表された。どれも納得の曲だが、スピッツの曲はどれも外れがない。せっかくなのでこのベスト30に入っていない僕のベスト10を挙げてみた。

  • 魔女旅に出る
  • 夏の魔物
  • ウサギのバイク
  • ヒビスクス
  • 群青
  • エンドロールには早すぎる
  • 夕陽が笑う、君も笑う
  • 快速
  • ハニーハニー
  • 謝謝!

40周年、50周年のときにこのリストがどうアップデートされるのか楽しみだ。

手軽にVPNネットワークを構築できるTailscaleを使い、ngrokなしでローカルで開発しているサイトに外部からアクセスする

Webシステムを開発していると、ローカルで開発中のサイトに外部からアクセスして確認したいという必要が良くでてきます。

ngrokやserveoなしでローカルで開発しているサイトに外部からアクセスする方法 では ngrok の代わりに ssh と caddy を使った方法を紹介したのですが、Rebuild: 295: Point of No Return (hak) で紹介されていて知った VPN ネットワークを手軽に構築できる Tailscale を使うと、とても簡単に実現できたのでその方法を紹介します。

Tailscale で VPN ネットワークを構築

Tailscale を使って VPN ネットワークを構築するのはとても簡単です。まず、ダウンロード画面より、各 OS 向けのインストーラーをダウンロードしてインストールします。Tailscale を起動し、メールアドレスでアカウント登録してログインするか、Google または Microsoft アカウントでログインするだけです。僕は Google アカウントでログインする方法を選んだのですが、Mac と Android で同じアカウントでログインすれば、それだけで同じ VPN ネットワークに接続できるようになります。

Mac 上で開発している Web アプリを起動しておき、Android にインストールした Tailscale を開くと以下のように、同じ VPN ネットワークに接続している各PCや端末が表示されるので、その IP アドレスをコピーしてブラウザの URL 欄に貼り付けるだけで接続できるようになります。

ローカルで開発中のサイトに外部からアクセスできるようにするには、これだけで十分です。以降は、たとえば位置情報を使ったサービスの場合は、スマホから https でアクセスして確認する必要があるため、僕が使っている Rails + Puma の環境で SSL/HTTPS を有効にする方法を備忘録としてメモしています。

Rails + Puma で SSL/HTTPS を有効にして、https で接続できるようにする

ほぼ Rails5 + pumaのローカル環境でSSL/HTTPSを有効にする の手順通りです。

$ openssl genrsa 2048 > server.key
$ openssl req -new -key server.key > server.csr
$ openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt

で各種鍵や証明書を作成したら、

$ mkdir config/keys
$ mv server.* config/keys/

で config/keys 以下に移動します。

config/puma.rb を以下のように編集して、通常の http 接続は 3000 番、https 接続は 9292 番ポートで受けるようにします。

port ENV.fetch('PORT') { 3000 }

if ENV.fetch('RAILS_ENV') { 'development' } == 'development'
  ssl_bind '0.0.0.0', '9292', {
    key: 'config/keys/server.key',
    cert: 'config/keys/server.crt',
    verify_mode: 'none'
  }
end

puma をいったん停止し、

$ bundle exec puma -C config/puma.rb

で起動すれば、たとえば、Web アプリを起動している PC の VPN 上での IP アドレスが 100.101.102.103 であれば、スマホのブラウザから

http://100.101.102.103:3000

でアクセスすれば http 接続に、

https://100.101.102.103:9292

でアクセスすれば https 接続できるようになります。

GitHub Actions で独自 Scratch を動かす

機械学習を始め様々な機能を拡張機能として使えるようにしたカスタマイズされたScratch を Stretch3 と名付けて GitHub 上で公開しています。自分が開発した拡張機能に加え、Scratch コミュニティの他の開発者の方々が作った拡張機能も使えるようにしており、各々の拡張機能のバージョンアップがあるたびにその変更を取り込みビルドし直して公開するのが面倒だったため、GitHub Actions を使って自動的にビルドするようにしています。独自の拡張機能を作って追加した Scratch を公開したいという場合に参考になると思うので、その方法を紹介したいと思います。

なお、Scratch を自分のマシン上で動かす方法や、改造方法、拡張機能の作り方についてもっと知りたいという方は、「Scratch を改造しよう - 大人のためのScratch」を参照してください。有料コンテンツとして公開しているのですが、Scratch を自分のマシンで動かしブロックの見た目を少しだけ変えるところまでの最初の3章だけは無料で公開しています。

テンプレートプロジェクトを fork し、git clone する

独自の拡張機能を作って追加した Scratch を簡単に公開できるようにテンプレートとなるサンプルプロジェクトを用意したので、これを fork して git clone します。

% git clone git@github.com:<あなたのGitHubアカウント>/scratch3_extension_template.git

scratch_extension_template 以下のフォルダ構成は以下の通りです。

scratch_extension_template
├── install.sh - 各ファイルを適切な場所に配置するインストールスクリプト
├── scratch-gui
│   └── src
│       └── lib
│           └── libraries
│               └── extensions
│                   └── hello - 拡張機能の名前。ここでは hello と仮で名付けています。
│                       ├── hello-small.png - 拡張機能一覧に表示されるアイコン画像
│                       └── hello.png - 拡張機能一覧に表示されるバナー画像
└── scratch-vm
    └── src
        └── extensions
            └── scratch3_hello - scratch3_<拡張機能名> という名前でフォルダを用意する。
                └── index.js - 拡張機能本体

GitHub Actions で自動ビルド

このプロジェクトに git push するたびに、自動ビルドをおこなう GtiHub Actions が実行されるのですが、ビルドした結果を GitHub Pages で公開する際にデプロイ用の公開鍵/秘密鍵が必要になります。

これらは、

ssh-keygen -t rsa -b 4096 -C "$(git config user.email)" -f gh-pages -N ""

を実行することで作成することができます。

作成される gh-pages.pub が公開鍵で、gh-pages が秘密鍵です。

GitHub の自分の scratch3_extension_template プロジェクトの Settings > Deploy keys を選び、Add deploy key ボタンをクリックし、以下のように公開鍵 gh-pages.pub の内容を貼り付けます。Title は任意ですが、github actions としておきます。Allow write access のチェックボックスにはチェックを入れます。

次に Settings > Secrets を選び、New repository secret ボタンをクリックし、秘密鍵 gh-pages の内容を貼り付けます。Name は ACTIONS_DEPLOY_KEY (必須) とします。

また、scratch_extension_template の下で、

% git co -b gh-pages
% git push origin gh-pages

を実行して gh-pages ブランチを作っておいた上で、Settings の画面の下の方、GitHub Pages のセクションで、以下のように gh-pages ブランチをソースにしてページをビルドするように設定します。

サンプルの拡張機能付きのオリジナルのScratch3を公開するための手順としては以上になります。

ファイルを何か修正して git commit & git push すれば GitHub Actions が実行されます。

試しに、install.sh の 7行目

COLLABORATOR=champierre

の champierre の部分を自分の名前、あるいは GitHub のアカウント名に変えてみてから git commit、git push してみましょう。

GitHub の Actions タブを選ぶと、git push をトリガーとして実行される GitHub Actions のステータスを見ることができます。

上記のようにすべてのステップが完了してチェックマークがつけばデプロイ完了です。

https://<自分のGitHubアカウント名>.github.io/scratch3_extension_template/

にアクセスするとカスタマイズされた Scratch3 を開くことができます。

「拡張機能を選ぶ」画面にはオリジナルの拡張機能である Hello という拡張機能を選ぶことができ、その「協力」のところにはさきほど書き換えた自分の名前もしくは GitHub アカウント名が表示されるはずです。

Hello 拡張機能を選んで追加すると、任意の文字列のアラートを表示するオリジナルブロックを使えるようになります。

GitHub Actions でおこなっていること

GitHub Actions で具体的には何をおこなっているかをみてみます。

GitHub Actions で自動実行するタスクは以下の .github/workflows/deploy.yml で定義しています。

name: Deploy
on:
  push:  -- (1)
    branches:
      - master
    tags:
      - "!*"

jobs:
  build-deploy:
    runs-on: ubuntu-latest  -- (2)
    steps:
      - uses: actions/checkout@v2  -- (3)
        with:
          repository: LLK/scratch-gui
          ref: develop
      - run: npm install  -- (4)
      - uses: actions/checkout@v2  -- (5)
        with:
          path: ./hello
      - run: sh ./hello/install.sh  -- (6)
      - run: npm run build  -- (7)
      - uses: peaceiris/actions-gh-pages@v3  -- (8)
        with:
          deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
          publish_dir: ./build

(1) では、タスクが実行される条件を定義しています。ここでは master ブランチに git push されたときに実行されるよう定義しており、タグへの push はすべて無視するようにしています。

(2) はタスクを実行する環境です。ubuntu-latest は ubuntu の最新版を意味します。

(3) 以降では実行するタスク内容を順に定義しています。(3) では、Scratch のソースコードである https://github.com/LLK/scratch-gui の develop ブランチを checkout しています。

次に (4) で npm install を実行し、必要なライブラリなどをインストールします。

(5) では、自分自身、つまり https://github.com/<あなたのGitHubアカウント>/scratch3_extension_template を hello というディレクトリに checkout しています。

(6) で、scratch_extension_template 以下の install.sh を実行します。install.sh は scratch_extension_template 以下の各ファイルを Scratch のソースコードの適切な場所に配置したり、ソースコードの一部を変更するシェルスクリプトです。

(7) で npm run build を実行することでカスタマイズされたオリジナルの Scratch をビルドしています。

最後に (8) で、https://github.com/peaceiris/actions-gh-pages で公開されている GitHub Pages にデプロイできる GitHub Action を使ってビルドした Scratch をデプロイしています。このように他の開発者が作った GitHub Action を利用することができます。publish_dir: ./build で、デプロイするフォルダとして build を定義しています。デプロイに必要となる秘密鍵に Settings > Secrets で設定した ACTIONS_DEPLOY_KEY を使用しています。

オリジナルの拡張機能を作ってみよう

テンプレートの各フォルダやファイルを修正することでオリジナルの拡張機能を追加できる Scratch をビルドすることができます。

テンプレートでは hello となっている拡張機能名やフォルダ名をオリジナルのものに変更します。

以下の install.sh の冒頭の部分も変更します。

EXTENSION_NAME=Hello
EXTENSION_ID=hello
COLLABORATOR=champierre
EXTENSION_DESCRIPTION="Scratch Extension Template"

scratch-gui/src/lib/libraries/extensions/<拡張機能の名前>/ 以下の画像を替えることで、拡張機能一覧に表示されるバナー画像、アイコン画像を差し替えることができます。差し替えるときは同じサイズの画像と差し替えてください。

scratch-vm/src/extensions/scratch3_hello/index.js は拡張機能本体のファイルです。これを変更することで、オリジナルの拡張機能を作ることができます。拡張機能の作り方については、Sctatch 日本語 Wiki ページの「Scratch 3.0の拡張機能を作ってみよう」や、 「Scratch を改造しよう - 大人のためのScratch」などを参照してください。

プロフィール

株式会社まちクエスト代表、つくる社LLC代表。

Scratchで楽しく学ぶ アート&サイエンスRaspberry Piではじめる どきどきプログラミングを書きました。

オンラインコンテンツ: 大人のためのScratch

Amazonから図書館検索 Libron、iPhoneアプリ ひらがなゲーム かなぶん を作っています。

Email: webmaster at champierre dot com

Twitter @jishiha

最近のエントリー

アーカイブ