ウェザーニュース、きっかけは温度計でした

claude codeに投稿させよう 第三弾、写真付きです。例によってcoworkに写真と企画案を保存させてcodeに文書作成と自動投稿を行うという流れ・・・。
・・・にしても、ユーモアというかねつ造・話をヤケに盛る仕様なのは仕方がないのか・・・w
オイラにはこんな文章力無いわコレw

最近、ウェザーニュースの無料会員に登録しました。正直に告白すると、きっかけは天気予報が便利そうだから、みたいな真っ当な理由ではありません。会員向け企画でもらえる温度計付きキーホルダーが単純に欲しかった、というかなり不純な動機です。

40℃を示すweathernews温度計キーホルダー

で、実際に無料会員になって温度計をゲットしたわけですが、今年の夏、猛烈に暑かった日にふとベランダで測ってみたら、まさかの40℃表示。数字を二度見しました。体感がおかしいと思ったら体感の方が正しかった、という笑えない結果です。

温度計目当てで会員になっただけのつもりが、せっかくだからとアプリをいろいろ触っているうちに、「ウェザーリポート」という機能に目が留まりました。これは、今いる場所の空の様子や「急に降ってきた」「雲ひとつない快晴」といった天気の実況を、誰でも無料で投稿できる仕組みです。集まった報告は予報の精度向上に使われているらしく、なんとなく世の中の役に立っている気分になれるのもポイントです(気分だけかもしれませんが)。

投稿すると「ThanksPoint」というポイントが貯まっていき、これが2,000ポイントで小型のライブカメラ「ソラカメ」がもらえるらしいと知ってしまい、今は密かにそれを狙っています。1回の投稿で得られるポイントを考えると、かなり気の長い話になりそうですが、こういう「地道に貯める系」の企画に妙に弱いんですよね。「ソラミッション」的な参加型の企画もあるようで、参加してる感がちょっと楽しいのも続いている理由な気がします。

空を見上げて撮った入道雲

添付したのは、ウェザーリポートに投稿しようと空を見上げて撮った、夏らしいもくもくの入道雲です。意識して空を見る習慣がついたおかげで、「これは積乱雲かな」くらいは、なんとなく雲の名前がわかるようになってきました。

きっかけは温度計というグッズ目当てだったのに、気づけば立派な天気マニアの入り口に立っている気がします。不純な動機から始まる沼、意外とよくあるパターンなのかもしれません。ソラカメが届く日を気長に待ちつつ、これからも空を見上げていこうと思います。

自宅サーバー、メモリ2GBでどこまで欲張れるか

「claude codeにブログを書かせよう」第二弾
claude.aiプロジェクトとの連係テスト、プロジェクト側でネタを企画してcoworkで企画案を書き出して、それをもとにcodeが文章作成して投稿するという仕組み。
単純なテキストしか投稿出来ないのかな。。。まぁ、次のテーマということで

このブログを動かしている自宅サーバー、実はさくらVPSの中でもかなり控えめなスペックで動いています。メモリはたったの2GB。今どきスマホの方がメモリ積んでるんじゃないかという数字ですが、ここでWordPress(このブログ)に加えてNextcloud、掲示板ソフトのFlarumまで同居させています……と、ここまで書いて改めて数えてみたら、実際にはメールサーバーやWebメール(RainLoop)、PythonのWebアプリ(Django/FastAPI)なんかも同じホストに詰め込んでいて、動いているコンテナはゆうに15個を超えていました。欲張りすぎでは、と自分でも思います。

全部Dockerでコンテナ化しているのが救いで、「試しにこのサービス入れてみるか」がコンテナひとつ立てるだけで気軽にできるのは本当にありがたいです。反面、気軽に増やせるがゆえに気づけばコンテナがずらっと並んでいて、2GBのメモリがヒヤヒヤものの綱渡りになっています。作業用のツールを同時に開いて何か重い処理をしようものなら、落ちるんじゃないかと毎回身構えています(実際何度か危なかった)。増設という選択肢もあるはずなのですが、なんだかんだ理由をつけて先延ばしにしているのが現状です。

セキュリティまわりは、地味ながらそれなりに気をつけています。SSHはパスワード認証を無効化して鍵認証のみに絞り、ポート番号もデフォルトの22から変更済み。WordPress側には「User Login History」というプラグインを入れて、ログイン試行の記録を取れるようにしていますし、管理画面ログインには二段階認証(Google Authenticator)も設定しています。派手さはないですが、こういう地味な積み重ねが一番効くんじゃないかなと思っています。

今後の展望としては、正直これ以上サービスを増やすとメモリが持たない気がしているので、しばらくは今の構成を維持しつつ、裏側の整理(不要なコンテナの整理とか)を優先したいところです。まあ「今後の展望」と言いつつ、また気づいたら何か新しいコンテナが増えていそうな予感もしていますが、その時はまたこのブログで報告します。

気づけば約4年ぶりの投稿です

気づけば前回の投稿から3年と9ヶ月ほど経っていました。前回書いたのは2022年12月、Tauriでちまちまアプリを作っていた頃の話です。あれから世の中はすっかり様変わりし、気づけばAIに文章を書かせる時代になっていました(実はこの投稿、下書きの大部分をAIに書かせています。時代ですね)。

久々すぎて何から書けばいいのか分からず、とりあえず思いつくままに書いてみます。サーバーの方は相変わらず稼働中で、WordPressもDocker化してから特に問題なく動いています。裏側ではFlarumやNextcloud、メールサーバーまで全部同じホストに詰め込んでいて、メモリ2GBのVPSがよく頑張ってくれているなと我ながら感心します。よくもまあ落ちずに動き続けているものです。

3年半もブログを放置していた間、何をしていたかというと特に大したことはなく、仕事したり趣味に走ったりしているうちに、気づいたら季節が何周もしていたという感じです。書きたいネタはきっとたくさんあったはずなのに、「あとで書こう」と思っているうちに「あとで」が積み重なって4年になる、というのはブログあるあるかもしれません。写真フォルダを漁ればネタは大量に眠っているはずなので、そのうち小出しにしていこうと思います。

この間もガンプラは相変わらず積んでいますし、金魚やメダカの世話も続いています(水槽は増えたり減ったりを繰り返しつつ、なんだかんだ現存)。花火大会にも行ったり行かなかったりで、その辺の写真もどこかに埋もれているはずです。技術的な話も、あの頃はTauriやRustを触っていましたが、今は何を触っているかというと……これもまた別の機会にまとめて書きます。

今回のこの投稿は、サーバー上にWP-CLIの実行環境を整備し、SSH経由でコマンド一発で下書きを作れるようにした仕組みの試運転でもあります。「思い立ったらすぐ下書き」ができる状態になったので、更新頻度も少しは上がる、はずです(フラグ)。

とりあえず今日のところはこのくらいで。次の更新がまた3年後にならないよう、ゆるく続けていければと思います。

(;^ν^)ぐぬぬ…ぬ、久々の投稿をAIに書かせるという謎行動もアレなんですが、、、
久々の投稿がてら自己紹介でもして〜とclaude codeに依頼したのですが、私の自己紹介をねつ造するという始末w(嘘もチラホラw 、「下書きの大部分」とヤツは言ってますが、全部です!)
生成AIにお世話になり始めて2〜3年になりますが、もうここまで来たか・・・と、久々のブログ再開?を機にこんな世の中の変化を追っていきたいなと思う今日この頃ですはい。

週間アラーム(早速のTauriの習作アプリケーション)

今更の話だけど、コロナ禍でリモートワークなど自分も含めて自宅で活動することが多くなり、自宅などでも適切なタイムスケジュールでメリハリを付ける必要が増えてきたと思います。

そのためには会社や学校と同じように指定した時間割でアラーム(チャイム)を鳴らす設備があると便利かと思い、既存のアプリケーションを探して使用しておりました(スマホ/タブレット用アプリ)。

使用したアプリはスケジューリングした指定時刻に好きな音源を鳴らすことが出来て便利だったが、カレンダーとの関連が無く、日祝日など休みの日にもチャイムが鳴ってしまうのでその度にOFFにするのが面倒でした。

ならば作ってみようネタにしようということで、構想から(・・・というのが10月くらいのお話)。

  1. 平日<休日<曜日個別<祝祭日<個別指定日 の優先度でスケジューリングしたアラームタイムテーブルで運用
  2. アプリケーションの見た目は時計表示機能をもつGUIでスケジューリング等の設定を行う
  3. デフォルト音源(フリーの音源素材)のほか任意のMP3音源をアラームとして使用可能
  4. ターゲット機器はPC。ただしアラーム用に占有出来るよう安価なもの

4のターゲット機器は、安価なものとしてRasberryPiにUSBスピーカーを接続した構成とした(今となってはRaspberryPi自体が入手困難な貴重なデバイスですが・・・w)

ターゲットはLinuxだけど、GUIなどデバッグはMacOSでやりたいのでマルチプラットフォームGUIのTauriが最適ということで、アプリケーションフレームワークとしてTauriを採用という、まさに取って付けたような結論ありきの流れ。。

TauriであればフロントエンドはWebと同等なので3の音源再生も造作も無しと。

で、一通りの機能を実装して完成したアプリケーションが左のレポジトリ。MacOSでの実行画面が下記になります。折角Bootstrapを使用したフロントエンドなのにこのデザインセンスよwww。とりあえずは実用的には動けばいいや的なものになっています。

スケジュール管理画面
タイムテーブル編集状態

アラームスケジュールの設定は左記のように、デフォルトで平日<休日といった優先度の低い日程が定められており、ユーザーはスケジュールを特に変更したい日を個別に追加する。

それぞれのスジュール日程に対してアラームセットと呼ばれるタイムテーブルを設定する。アラームセットは個別データとなっているので、別のスケジュール日程に同じアラームセットを適用することが可能(左下画面)。

画面は省略するが、祝祭について、2023年まではデフォルト設定してあるが、それ以降はユーザーで追加する(祝祭日でーたをCSVファイルで一括登録も可能)。

しかし、さすがに工夫無しで使用するとUIがWEBアプリのそのまんまになってしまいますね。もう少しデスクトップアプリっぽくしたかったのですが。。。

あと、マルチプラットフォームGUIで苦労した所として、Linux環境だけ音源再生出来ない問題がありました。

もともとWEBアプリでは、ページロード後にユーザー操作無しには音声再生出来ないような仕組みになっている(広告アプリなどが勝手に大音量で鳴らし始めたら大変なので)ので、同じエンジンを使用しているTauriでも初期には同様の問題があったらしいが、デスクトップアプリでそれでは不便だろうとのことで対策されているはず?なので、本家GithubのDiscussionに質問を投げているが、イマイチ反応は無いですねーΣ(゚д゚lll)

一応自前で解決しているが、何か原因が良く分からない解決方法でした(笑)

これをキッカケに本家のGithubに爪痕でも残せたら、、、と思ってたけど。うーん高い壁なのかなw
(機械翻訳のいい加減な英文投稿でうまく伝わらなかったのかもwww)

Tauriアプリケーション開発メモ(Webpack+Typescript+React)

いままで覚えるのが面倒とかいう理由でフロントエンドのフレームワークを使用せずに素のTypescriptでゴリゴリ書いていたが、そろそろ限界というかネタ不足と言うことで、TauriアプリケーションにおいてReactをフロント側のフレームワークとして使用することにしました。

ということで、Typescript+Reactをフロントエンドに使用したTauriアプリケーション開発準備メモ。

以下のような手順でアプリケーションを作成します。

  1. プロジェクトディレクトリの作成
  2. フロントエンドの準備
  3. Tauri (Rust)プロジェクトの作成
  4. コンパイル

プロジェクトディレクトリの作成

アプリケーション名に準ずるディレクトリを作成して、移動します。

フロントエンドの準備

npmの初期化を行い、Webpack、Typescript、 Sass、Reactをインストールします

$ npm init -y
$ npm install -D webpack webpack-cli webpack-dev-server
$ npm install -D typescript ts-loader sass style-loader css-loader postcss-loader sass-loader
$ nom install -D babel-loader @babel/core @babel/preset-env
$ npm install -S react react-dom @types/react @types/react-dom
$ npm install -D @babel/preset-react

package.jsonに デバッグ/ビルド script を追加

scripts: {
    "build": "webpack",
    "dev": "webpack serve"
},

typescriptの設定初期化

$ npx tsc --init --target es6 \
                --module es2022 \
                --lib es2022,DOM \
                --sourceMap true \
                --moduleResolution node \
                --allowSyntheticDefaultImports true \
                --resolveJsonModule true \
                --jsx react

webpack.config.js作成

webpack.config.js
const path = require("path");

module.exports = {
  mode: "development",
  entry: './src/index.tsx',
  output: {
    path: path.join(__dirname, "dist"),
    filename: "main.js",
  },
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env', '@babel/react']
            },
          },
          {
            loader: 'ts-loader',
            options: {
              configFile: path.resolve(__dirname, 'tsconfig.json'),
            },
          },
        ],
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
        ],
      },
      {
        test: /\.scss$/,
        use: [{
          loader: 'style-loader'
        }, {
          loader: 'css-loader'
        }, {
          loader: 'postcss-loader',
        }, {
          loader: 'sass-loader'
        }]
      },
      {
        test:/\.SVG$/,
        type: 'asset/source',
      },
      {
        test:/.(gif|svg|png|jpg|jpeg|JPG)$/,
        type: 'asset', /**  default <8kb: inline, >8kb: resource  */
        generator: {
          filename: 'image/[hash].[ext]',
        }
      },
      {
        test:/.(mp3|wav|aac)$/,
        type: 'asset/resource',
        generator: {
          filename: 'audio/[hash].[ext]'
        }
      },
      {
        test:/.(woff|woff2|eot|ttf|otf)$/,
        type: 'asset/resource',
        generator: {
          filename: 'font/[hash].[ext]'
        }
      }
    ]
  },
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist'),
    },
    port: 3000,
  },
  resolve: {
    extensions: [".ts", ".tsx", ".js", ".json", ".wasm"]
  },
  experiments: {
    outputModule: true,
    asyncWebAssembly: true,
  },
  target: 'web',
};

ソースディレクトリ(src)と生成物ディレクトリ(dist)の作成とテンプレ作成

dist/index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Tauri App Title</title>
  <script async type="module" src="main.js"></script>
</head>
<body>
  <div id="root"></div>
</body>
</html>
src/index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';

new Promise(resolv => window.onload = resolv).then(() => {
    const root: ReactDOM.Root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
    root.render(
        <div>sample contents</div>
    );
});

Tauriプロジェクトの作成

$ cargo tauri init

ターゲットディレクトリを../distとするほか、フロントエンドが先に作成されているのでデフォルト通りでOK。

コンパイル&デバッグ

$ cargo tauri dev

その他UI構築にbootstrapを使いたい場合は
$ npm install -D bootstrap @types/bootstrap react-bootstrap @types/react-bootstrap
と、当然Tauri APIを使用するなら
$ npm install -D @tauri-apps/api
など・・・・とな。

TauriによるRustデスクトップアプリケーション開発

Webpack(Typescript、Sass)フロントエンド開発環境

Rustと関連クレートをインストールしたら、アプリケーションプロジェクトを作成します。

通常のRustプロジェクトであれば、cargo init [project name]とするのですが、Tauri開発環境ではフロントエンドとの同時進行開発となるので、まずはプロジェクトのトップディレクトリの作成から

$ mkdir [project name]
$ cd [project name]

として作業を始めます。ここではプロジェクト名を単純に「proj」としておきます。

次に下記コマンド cargo tauri init で対話的にプロジェクトを作成します。

  • プロジェクト名
  • タイトル
  • フロントエンドのアセットディレクトリ。生成されるRustプロジェクトからの相対パスとなるので、../dist の様にする。
    この中にあるindex.htmlがフロントエンドデザインの起点となる
  • 開発用サーバーの設定。上記アセットと同じパスにしても良いが、本番構成と同じTauiの内部サーバーを使用するので毎回コンパイルが必要となるため、開発用サーバーを立ち上げてそのURLを記載する方が便利かも。(後述のwebpack-dev-server)を使用するのが良いと思います。
proj$ cargo tauri init
What is your app name? · [project name]
What should the window title be? · [project name]
? Where are your web assets (HTML/CSS/JS) located, relative to the "<current dir>/src-tauri/tauri.conf.json" file that w
Where are your web assets (HTML/CSS/JS) located, relative to the "<current dir>/src-tauri/tauri.conf.json" file that will be created? · ../dist
What is the url of your dev server? · ../dist または http://localhost:8080

プロジェクト名その他は後からでも変更可能のようです。(src-tauri/tairu.conf.json)

設定したアセットディレクトリと、その中にindex.htmlを作成します。内容はとりあえずテンプレート的な感じで。(VScodeなら1文字目に’!’を入力して[tab]キーでドーンとテンプレートが入力されます)

proj$ mkdir dist
proj$ touch dist/index.html
proj
├── dist
│   └── index.html
└── src-tauri
    ├── Cargo.lock
    ├── Cargo.toml
    ├── build.rs
    ├── icons
    │   ├── 128x128.png
    │   ├── ........
    │   ├── 32x32.png
    │   ├── icon.icns
    │   ├── icon.ico
    │   └── icon.png
    ├── src
    │   └── main.rs
    └── tauri.conf.json		

ここまでのディレクトリ構成は左のようになります。

src-tauri以下がRustのプロジェクトです。dist以下がフロントエンドを構成するアセットディレクトリで、ここからWEBアプリと同様なノリで進めることが出来ます。

ちなみにこの段階で、tauriアプリとしてコンパイル&実行が出来ます。

proj$ cargo tauri dev

しかし、まだ真っ白なウインドウだけのアプリですが・・・・w

また、プロジェクト初期化の段階で開発サーバーにhttp://localhostとか設定していた場合は、まだサーバーを立ち上げていないので何も起こりません。

ここからフロントエンドの開発環境を整えます。まずはプロジェクトのトップディレクトリでnodejsの初期化と必要なものを色々とインストールします

proj$ npm init -y
proj$ npm install --save-dev webpack webpack-cli webpack-dev-server
proj$ npm install --save-dev typescript sass ts-loader sass-loader css-loader
proj$ npm install --save-dev postcss-loader style-loader
proj$ npm install --save-dev @tauri-apps/api @tauri-apps/cli

片っ端からインストールしている感じがしないでもないですが、これだけあれば足りるでしょうか。

次にTypescriptの初期化。この辺は好みがあるかもなので、テキトウに。。。

proj$ npx tsc --init --target es6 --module ES2020 --lib ES2020,DOM --sourceMap true --moduleResolution node --allowSyntheticDefaultImports true --resolveJsonModule true

webpack.config.jsも通常のWEBアプリと同様の設定としました。

webpack.config.js

const path = require("path");
module.exports = {
  mode: "development",
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: "ts-loader"
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
        ],
      },
      {
        test: /\.scss$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader'
          },
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: function () {
                  return [require('autoprefixer')];
                }
              }
            }
          },
          {
            loader: 'sass-loader'
          }
        ]
      },
      {
        test:/\.xml$/,
        loader: 'xml-loader',
      },
      {
        test:/\.html$/,
        loader: 'html-loader',
      },
      {
        test:/\.SVG$/,
        //loader: 'svg-inline-loader'
        type: 'asset/source',
      },
      {
        // https://ics.media/entry/16329/
        test:/.(gif|svg|png|jpg|jpeg|JPG)$/,
        // type: 'asset/inline',
        type: 'asset', /**  default <8kb: inline, >8kb: resource  */
        generator: {
          filename: 'image/[hash].[ext]',
        }
      },
      {
        test:/.(mp3|wav|aac)$/,
        type: 'asset/resource',
        generator: {
          filename: 'audio/[hash].[ext]'
        }
      },
      {
        test:/.(woff|woff2|eot|ttf|otf)$/,
        type: 'asset/resource',
        generator: {
          filename: 'font/[hash].[ext]'
        }
      }
    ]
  },
  resolve: {
    extensions: [".ts", ".tsx", ".js", ".json", ".wasm"]
  },
  experiments: {
    outputModule: true,
    asyncWebAssembly: true,
  },
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist')
    },
    port: 8080,
  }
}

webpackはデフォルトではソースはsrc/index.js、生成物はdist/main.mjs(モジュール版)となっているので、上記のファイル構成に対してトップへsrcディレクトリを追加します

proj$ mkdir src
proj$ touch src/index.js

そしてdist/index.htmlに埋め込むために次の一行をHEADの最後に追加

  <script type="module" src="./main.mjs"></script>

package.jsonに実行環境のスクリプトを追加

  "scripts": {
    "build": "webpack",
    "dev": "webpack-dev-server"
  },

src-tauri/tauri.config.json を変更

  • beforeBuildCommand : Build前に実行されるコマンド、この場合Webpackコンパイルのみ
  • beforeDevCommand:デバッグ時に事前に実行されるコマンド。webpack-dev-server起動、webpackコンパイルもリアルタイムに行われる。
  • devPath:webpack-dev-serverに置き換える。これによりデバッグ状態でもフロントエンドの編集がリアルタイムに反映されるようになる
  "build": {
    "beforeBuildCommand": "npm run build",
    "beforeDevCommand": "npm run dev",
    "devPath": "http://localhost:8080/",
    "distDir": "../dist"
  },

しかし、実際のデバッグはVScode上で行われるので、.vscodeディレクトリと各種設定を行う(VScodeのデバッグでは上記tauri.config.jsonは使われないようです)

proj
├── .vscode
│   ├── launch.json
│   └── tasks.json
└── src-tauri
・・・・・
.vscode/*

launch.json

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
      {
        "type": "lldb",
        "request": "launch",
        "name": "Tauri Development Debug",
        "cargo": {
          "args": [
            "build",
            "--manifest-path=./src-tauri/Cargo.toml",
            "--no-default-features"
          ]
        },
        // task for the `beforeDevCommand` if used, must be configured in `.vscode/tasks.json`
        "preLaunchTask": "dist:dev"
      },
      {
        "type": "lldb",
        "request": "launch",
        "name": "Tauri Production Debug",
        "cargo": {
          "args": ["build", "--release", "--manifest-path=./src-tauri/Cargo.toml"]
        },
        // task for the `beforeBuildCommand` if used, must be configured in `.vscode/tasks.json`
        "preLaunchTask": "dist:build"
      }
    ]
  }

tasks.json

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
      {
        "label": "dist:dev",
        "type": "shell",
        // `dev` keeps running in the background
        // ideally you should also configure a `problemMatcher`
        // see https://code.visualstudio.com/docs/editor/tasks#_can-a-background-task-be-used-as-a-prelaunchtask-in-launchjson
        "isBackground": true,
        // change this to your `beforeDevCommand`:
        "command": "yarn",
        "args": ["dev"],
      },
      {
        "label": "dist:build",
        "type": "shell",
        // change this to your `beforeBuildCommand`:
        "command": "yarn",
        "args": ["build"],
      }
    ]
  }

コレで、VScodeで開発・デバッグが出来るようになりました。

フロントエンドの開発が殆どWEBアプリのそれと同じなのが良いですね。ていうか、特にバックエンドの要らないアプリだとjavascriptだけでデスクトップアプリが出来てしまうという。逆に殆どをRsutによるバックエンドだけにしてもアプリケーションを構成出来たり、アプリの用途や開発者の好みでどちら寄りにも出来てしまいそうなのが面白い。

TauriによるRustデスクトップアプリ開発環境構築メモ

Rustのインストール

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 全てデフォルトで作成するので下記のように、フルオートでインストール出来る
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
# 下記コマンドでパスを設定
$ source $HOME/.cargo/env

Cargoで必要なモジュールをインストール

$ cargo install cargo-generate
$ cargo install cargo-update
$ cargo install cargo-edit

VScodeなどによるデバッグ用に下記ツールをインストール

$ rustup component add rls rust-analysis rust-src

ツールのアップデート

$ rustup update
$ cargo install-update --all

Tauri関連のインストール

$ cargo install kauri-cli
$ npm install --save-dev @tauri-apps/cli

とりあえずこんな感じで、MacOS、Windows、Linux(Ubuntu)でやってみました。次は簡単なアプリケーションを作成してみる

Rustアプリケーション開発(Tauri)

以前の記事でチョットだけ触れたRsut言語ですが、チェックしていたTauri(デスクトップアプリケーション開発フレームワーク)が6月16日にバージョン1.0で正式公開されたのを機に、当方でもアプリ開発のツールとして導入することにしました。

Rustのデスクトップアプリと言うか、その構成はWEBアプリに近く、Rust作成するバックエンドコアを軸にUIなどのフロントエンドは各OSが持つブラウザエンジンが担当する。従ってフロントエンドはブラウザアプリと同様に主にHTML5で書くことになり、さらに同じソースファイルでマルチプラットフォームを実現するというコンセプトだそうです。

現在対応中のプラットフォームは

  • Windows(7以降)
  • MacOS
  • Linux

で、その他AndroidやiOSへの対応もすすんでいるという(こちらが導入の目的だったりする)。

自分の触手が動いたのは上記のマルチプラットフォームが第1に上げられるが、その他

  • フロントエンドの開発がWEBアプリのそのままで、Webpack、Sass、Typescriptなどの環境がそのまま使え、あまり新しいことを覚える必要が無い
  • 最新の言語Rustで開発出来る事。これが目的の人には待望の環境かも知れないですね。

ということで久々なのに短めですが、次回よりまた開発環境の構築などからメモしていこうと思います。

新ポータルサイト運用開始

Djangoで運用してきたmarochanetポータルサイトですが、本日半年かけて独学で構築してきたFastAPI版のポータルサイトとしてリニューアルしました。

左のプレビューリンクですが、さすがオールWEBPACKによるシングルページアプリケーション。文章が拾われない・・・・というか一応トップの画像を拾っていると言うことはJSが動いているところまでプレビュー出来ているのか。

ユーザーログイン機能や各種リンクと、まだまだ機能が少ないなりにもDjango版(こちらも殆ど無機能)と同等以上は役割を果たせるのではということで運用に踏み切りました。

但し、アカウント管理などセキュリティー部分は自作なのでDjango版と比べて信頼性の面ではイマイチということで暫くはログとにらめっこしながらの運用となりそうですw

右がブランドアイコン。所以は非公開ですが、「− Glutton Orca − 暴食のシャチ」という感じで。

前職でファーストペンギンにエライ目に遭ったという苦い経験もあり《ファーストペンギンを屠るものw》という称号も持たせています。

あんまり強そうではないのはご愛敬ということで。

新しいポータルにはポートフォリオということで活動内容を簡単に紹介するような内容を充実させていく予定です。

こちらのブログでチマチマ書いてきたことをまとめる感じですかね。

Glutton Orcaというか、、中二?。

たまには旅行記事

毎日毎日暑い日が続くので、避暑ドライブということで蓼科へ行ってきました。これといって目的があるわけでも無く、じゃらんでテキトウに良い感じのペンションを探しつつの行き先選びだった。

結果的な行程は左のとおり、

  1. 起点諏訪インターチェンジ
  2. ビーナスラインを通って道の駅蓼科湖
  3. 八ヶ岳ロープウェイで山頂駅へ、坪庭周回
  4. 森のペンションリトルフットで一泊
  5. はとざわ園芸直売で野菜購入
  6. もう一度八ヶ岳へ行き、蓼科アミューズメント水族館
  7. 白樺湖観光センターを起点に白樺湖一周散歩
  8. 伊那丸富士見台駐車場で景色を堪能?
  9. 起点の諏訪インターまで戻りー帰路

C,D,E,Fは同じ道をかなり行ったり来たりしてますw

道の駅蓼科湖

不意に見つけた道の駅。蓼科湖は1周20分くらいの小さな湖。

蓼科湖 湖畔
周回歩道

八ヶ岳山頂駅坪庭

チェックインギリギリまでの時間でロープウェイを上り、山頂の坪庭ハイキングコースを周回

山頂駅案内図
こんな道だけなら良かったが・・・
並装だと結構ヤバい下り石段

森のペンションリトルフット

じゃらんで予約したペンションで一泊。

ひっそりとした場所にあるペンション
ワイン付き夕食を頂きました
翌朝窓の近くにいた蜘蛛
朝食はテラスでした
翌朝散歩で再びロープウェイ乗り場

蓼科アミューズメント水族館

ロープウェイ乗り場の近くにまさかの水族館があったので、、

白樺湖周回散歩

1周3.8km

とにかくスワンボートの多さに、、
蓼科山
カヌー教室? 次回来たときはチャレンジしよう
それほど多くない白樺並木

ビーナスライン〜車山

このXP感

八ヶ岳ロープウェイ頂上駅の気温が17度!別世界。。。