約束の地 2024-03-15T05:30:00+09:00 gregminster Hatena::Blog hatenablog://blog/12921228815715016836 Rails で datetime型 にテキストをそのまま入れる形で find_or_initialize_by でレコード操作したらタイムゾーンが異なっていたためすべて新規レコードになってしまった hatenablog://entry/6801883189066673100 2024-03-15T05:30:00+09:00 2024-03-15T05:30:00+09:00 前提 find_or_initialize_by にこだわるのは本質的ではなく、find_by や where などでも同じです。本質はタイムゾーンの違いです。 結論 具体例を見たほうが早いと思いますので、載せます。 NG な例 user = User.find_or_initialize_by( name: 'hoge', submitted_at: '2023/04/07 17:48:31' ) これを繰り返し実行した場合に、常に user.new_record? が true を返してしまいます。 OK な例 期待通りの動作をさせるためには、テキストでそのまま入れるのではなく Time.… <h1 id="前提">前提</h1> <p><code>find_or_initialize_by</code> にこだわるのは本質的ではなく、<code>find_by</code> や <code>where</code> などでも同じです。本質はタイムゾーンの違いです。</p> <h1 id="結論">結論</h1> <p>具体例を見たほうが早いと思いますので、載せます。</p> <h4 id="NG-な例">NG な例</h4> <pre class="code lang-ruby" data-lang="ruby" data-unlink>user = <span class="synType">User</span>.find_or_initialize_by( <span class="synConstant">name</span>: <span class="synSpecial">'</span><span class="synConstant">hoge</span><span class="synSpecial">'</span>, <span class="synConstant">submitted_at</span>: <span class="synSpecial">'</span><span class="synConstant">2023/04/07 17:48:31</span><span class="synSpecial">'</span> ) </pre> <p>これを繰り返し実行した場合に、常に <code>user.new_record?</code> が <code>true</code> を返してしまいます。</p> <h4 id="OK-な例">OK な例</h4> <p>期待通りの動作をさせるためには、テキストでそのまま入れるのではなく <code>Time.zone.parse</code> します。</p> <p><strong>ただし、データソースによってはタイムゾーンには注意が必要です</strong>(<a href="https://qiita.com/aosho235/items/a31b895ce46ee5d3b444">こちら</a>などを参照)。</p> <pre class="code lang-ruby" data-lang="ruby" data-unlink>user = <span class="synType">User</span>.find_or_initialize_by( <span class="synConstant">name</span>: <span class="synSpecial">'</span><span class="synConstant">hoge</span><span class="synSpecial">'</span>, <span class="synConstant">submitted_at</span>: <span class="synType">Time</span>.zone.parse(<span class="synSpecial">'</span><span class="synConstant">2023/04/07 17:48:31</span><span class="synSpecial">'</span>) ) </pre> <p>これで <code>find</code> でちゃんと見つけてきてくれます。</p> <h1 id="検討">検討</h1> <p>SQL を見てみるとよく分かります<a href="#f-94b304e1" id="fn-94b304e1" name="fn-94b304e1" title="PostgreSQL を使用しています">*1</a>。</p> <h4 id="NG-な例-1">NG な例</h4> <pre class="code lang-ruby" data-lang="ruby" data-unlink><span class="synType">User</span>.find_by(<span class="synConstant">submitted_at</span>: <span class="synSpecial">&quot;</span><span class="synConstant">2023/04/07 17:48:31</span><span class="synSpecial">&quot;</span>) <span class="synComment">#=&gt; SELECT &quot;users&quot;.* FROM &quot;users&quot; WHERE &quot;users&quot;.&quot;submitted_at&quot; = $1 LIMIT $2 [[&quot;submitted_at&quot;, &quot;2023-04-07 17:48:31&quot;], [&quot;LIMIT&quot;, 1]]</span> </pre> <h4 id="OK-な例-1">OK な例</h4> <pre class="code lang-ruby" data-lang="ruby" data-unlink><span class="synType">User</span>.find_by(<span class="synConstant">submitted_at</span>: <span class="synType">Time</span>.zone.parse(<span class="synSpecial">&quot;</span><span class="synConstant">2023/04/07 17:48:31</span><span class="synSpecial">&quot;</span>)) <span class="synComment">#=&gt; SELECT &quot;users&quot;.* FROM &quot;users&quot; WHERE &quot;users&quot;.&quot;submitted_at&quot; = $1 LIMIT $2 [[&quot;submitted_at&quot;, &quot;2023-04-07 08:48:31&quot;], [&quot;LIMIT&quot;, 1]]</span> </pre> <div class="footnote"> <p class="footnote"><a href="#fn-94b304e1" id="f-94b304e1" name="f-94b304e1" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">PostgreSQL を使用しています</span></p> </div> gregminster Tailscale で SSH した場合には X11 forwarding が機能しない hatenablog://entry/6801883189066298732 2024-03-08T05:30:00+09:00 2024-03-08T05:30:01+09:00 現象 SSH でログイン時に、 X11 forwarding request failed on channel 0 というエラーが出ます。 結論 現時点では機能しない*1。 参考 github.com *1:将来的には動くかも <h1 id="現象">現象</h1> <p>SSH でログイン時に、</p> <pre class="code bash" data-lang="bash" data-unlink>X11 forwarding request failed on channel 0</pre> <p>というエラーが出ます。</p> <h1 id="結論">結論</h1> <p>現時点では機能しない<a href="#f-381654e7" id="fn-381654e7" name="fn-381654e7" title="将来的には動くかも">*1</a>。</p> <h1 id="参考">参考</h1> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Ftailscale%2Ftailscale%2Fissues%2F5160" title="ssh X11 forwarding doesn&#39;t work · Issue #5160 · tailscale/tailscale" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/tailscale/tailscale/issues/5160">github.com</a></cite></p> <div class="footnote"> <p class="footnote"><a href="#fn-381654e7" id="f-381654e7" name="f-381654e7" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">将来的には動くかも</span></p> </div> gregminster WSL2 で Tailscale (tailscaled) を自動で起動する方法 hatenablog://entry/6801883189066110089 2024-03-01T04:30:00+09:00 2024-03-01T04:30:01+09:00 結論 シェルの設定ファイルに例えば以下のように組み込む。 # Starting Tailscale daemon automatically if not running... RUNNING=`ps aux | grep tailscaled | grep -v grep` if [ -z "$RUNNING" ]; then sudo tailscaled > /dev/null 2>&1 & disown fi 補足 $ sudo tailscaled をパスワード確認無しで実行するために /etc/sudoers に追記をする必要がある*1 tailscaled の場所は which … <h1 id="結論">結論</h1> <p>シェルの設定ファイルに例えば以下のように組み込む。</p> <pre class="code bash" data-lang="bash" data-unlink># Starting Tailscale daemon automatically if not running... RUNNING=`ps aux | grep tailscaled | grep -v grep` if [ -z &#34;$RUNNING&#34; ]; then sudo tailscaled &gt; /dev/null 2&gt;&amp;1 &amp; disown fi</pre> <h1 id="補足">補足</h1> <ul> <li><code>$ sudo tailscaled</code> をパスワード確認無しで実行するために <code>/etc/sudoers</code> に追記をする必要がある<a href="#f-500ea57a" id="fn-500ea57a" name="fn-500ea57a" title="もちろん visudo 経由で">*1</a> <ul> <li><code>tailscaled</code> の場所は <code>which tailscaled</code> で調べる</li> </ul> </li> <li>これ以外の方法もあり得るが(次項の「参考」を参照)、この方法はシンプルだしシェル起動時間にもそんなに影響がないため、これがベターだと思う</li> <li>他の「スタートアップ時起動」したいアプリケーションもこの累計で起動できる<a href="#f-01a22bc6" id="fn-01a22bc6" name="fn-01a22bc6" title="少々強引な方法ではあるが">*2</a></li> </ul> <h1 id="参考">参考</h1> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Ftailscale%2Ftailscale%2Fissues%2F562%23issuecomment-1017392542" title="tailscaled doesn&#39;t start under WSL; no systemd · Issue #562 · tailscale/tailscale" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/tailscale/tailscale/issues/562#issuecomment-1017392542">github.com</a></cite></p> <div class="footnote"> <p class="footnote"><a href="#fn-500ea57a" id="f-500ea57a" name="f-500ea57a" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">もちろん visudo 経由で</span></p> <p class="footnote"><a href="#fn-01a22bc6" id="f-01a22bc6" name="f-01a22bc6" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">少々強引な方法ではあるが</span></p> </div> gregminster Activerecord-Import で大量のデータをバルクインポートしようとすると PostgreSQL が落ちる hatenablog://entry/6801883189065762887 2024-02-23T06:30:00+09:00 2024-02-23T06:30:02+09:00 Activerecord-Import とは github.com 結論(どうするか) インポート時に batch_size オプションを指定してやる。 具体例 User.import!(users, batch_size: 10000) PostgreSQL が落ちたときのエラーメッセージ PQconsumeInput() SSL SYSCALL error: EOF detected (ActiveRecord::ConnectionFailed) 参考 https://webcache.googleusercontent.com/search?q=cache:jdX4uXcvCb4J:h… <h1 id="Activerecord-Import-とは">Activerecord-Import とは</h1> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fzdennis%2Factiverecord-import" title="GitHub - zdennis/activerecord-import: A library for bulk insertion of data into your database using ActiveRecord." class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/zdennis/activerecord-import">github.com</a></cite></p> <h1 id="結論どうするか">結論(どうするか)</h1> <p>インポート時に <code>batch_size</code> オプションを指定してやる。</p> <h1 id="具体例">具体例</h1> <pre class="code lang-ruby" data-lang="ruby" data-unlink><span class="synType">User</span>.import!(users, <span class="synConstant">batch_size</span>: <span class="synConstant">10000</span>) </pre> <h1 id="PostgreSQL-が落ちたときのエラーメッセージ">PostgreSQL が落ちたときのエラーメッセージ</h1> <pre class="code bash" data-lang="bash" data-unlink>PQconsumeInput() SSL SYSCALL error: EOF detected (ActiveRecord::ConnectionFailed)</pre> <h1 id="参考">参考</h1> <p><a href="https://webcache.googleusercontent.com/search?q=cache:jdX4uXcvCb4J:https://system.blog.uuum.jp/entry/2022/10/11/131234&hl=ja&gl=jp">https://webcache.googleusercontent.com/search?q=cache:jdX4uXcvCb4J:https://system.blog.uuum.jp/entry/2022/10/11/131234&hl=ja&gl=jp</a><cite class="hatena-citation"><a href="https://webcache.googleusercontent.com/search?q=cache:jdX4uXcvCb4J:https://system.blog.uuum.jp/entry/2022/10/11/131234&hl=ja&gl=jp">webcache.googleusercontent.com</a></cite></p> gregminster SwitchBot の ブラインドポール を手動で充電する方法 hatenablog://entry/6801883189064785981 2024-02-16T03:30:00+09:00 2024-02-16T03:30:01+09:00 結論 ここです。設置場所を考えると数メートルの USBケーブル を用いるのが無難です。 長い USBケーブル は一本持っておくといろいろ便利で、たとえば SwitchBot のカーテンレールの充電にも役立ちます。 <h1 id="結論">結論</h1> <p>ここです。設置場所を考えると数メートルの USBケーブル を用いるのが無難です。</p> <p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/g/gregminster/20231207/20231207112528.jpg" width="675" height="1200" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> <p>長い USBケーブル は一本持っておくといろいろ便利で、たとえば SwitchBot のカーテンレールの充電にも役立ちます。</p> gregminster Ruby で "sh" を実行しようとしたら Not Found と言われたとき hatenablog://entry/6801883189064753388 2024-02-09T06:30:00+09:00 2024-02-09T06:30:01+09:00 結論 require 'rake' をする。 公式ドキュメント docs.ruby-lang.org <h1 id="結論">結論</h1> <p><code>require 'rake'</code> をする。</p> <h1 id="公式ドキュメント">公式ドキュメント</h1> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fdocs.ruby-lang.org%2Fja%2Flatest%2Fmethod%2FFileUtils%2Fi%2Fsh.html" title="FileUtils#sh (Ruby 3.3 リファレンスマニュアル)" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://docs.ruby-lang.org/ja/latest/method/FileUtils/i/sh.html">docs.ruby-lang.org</a></cite></p> gregminster .dot ファイル (Graphviz) を PDF に変換する方法 hatenablog://entry/6801883189064753067 2024-02-02T05:00:00+09:00 2024-02-02T05:00:02+09:00 結論 Graphviz (CLI) はインストール済みであるとします。 $ dot -Tpdf /path/to/hoge.dot -o /path/to/fuga.pdf 具体例 Rails ERD では dot で出力が可能なところ、その dot を PDF に変換するために有用です。 「Rails ERD で最初から PDF に出力すると Git で差分が分からない(毎回差分が出る)ので dot 運用したい」というようなケースで有効です*1。 公式ドキュメント *1:dot の差分が分かりやすいかと言われると決してそうではないのですが <h1 id="結論">結論</h1> <p>Graphviz (CLI) はインストール済みであるとします。</p> <pre class="code bash" data-lang="bash" data-unlink>$ dot -Tpdf /path/to/hoge.dot -o /path/to/fuga.pdf</pre> <h1 id="具体例">具体例</h1> <p><a href="https://github.com/voormedia/rails-erd">Rails ERD</a> では dot で出力が可能なところ、その dot を PDF に変換するために有用です。</p> <p>「Rails ERD で最初から PDF に出力すると Git で差分が分からない(毎回差分が出る)ので dot 運用したい」というようなケースで有効です<a href="#f-5a0bbbfa" id="fn-5a0bbbfa" name="fn-5a0bbbfa" title="dot の差分が分かりやすいかと言われると決してそうではないのですが">*1</a>。</p> <h1 id="公式ドキュメント">公式ドキュメント</h1> <div class="footnote"> <p class="footnote"><a href="#fn-5a0bbbfa" id="f-5a0bbbfa" name="f-5a0bbbfa" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">dot の差分が分かりやすいかと言われると決してそうではないのですが</span></p> </div> gregminster GitHub Actions で ubuntu-22.04 で Cypress を Firefox で実行する際は deb 版を入れる hatenablog://entry/6801883189064164533 2024-01-26T05:30:00+09:00 2024-01-26T05:30:02+09:00 結論 標題のとおりです。 具体的方法 参考ページ deb版の入れ方については以下のページが参考になります。 chatnoirlibre.com 99mozillateamppa の適用のさせ方 99mozillateamppa の適用のさせ方は、どこかに 99mozillateamppa という名前と内容のファイルを用意しておいて、ステップの中で、 sudo cp 99mozillateamppa /etc/apt/preferences.d を実行してあげるといいです。 ステップ全体での 99mozillateamppa の適用のさせ方 ステップ全体としては以下のような流れで実行していきます… <h1 id="結論">結論</h1> <p>標題のとおりです。</p> <h1 id="具体的方法">具体的方法</h1> <h3 id="参考ページ">参考ページ</h3> <p>deb版の入れ方については以下のページが参考になります。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fchatnoirlibre.com%2Fubuntu-22-04-lts-mozilla-firefox-deb%2F" title="Ubuntu 22.04 LTS に Mozilla Firefox の deb パッケージ版を導入する" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://chatnoirlibre.com/ubuntu-22-04-lts-mozilla-firefox-deb/">chatnoirlibre.com</a></cite></p> <h3 id="99mozillateamppa-の適用のさせ方"><code>99mozillateamppa</code> の適用のさせ方</h3> <p><code>99mozillateamppa</code> の適用のさせ方は、どこかに <code>99mozillateamppa</code> という名前と内容のファイルを用意しておいて、ステップの中で、</p> <pre class="code bash" data-lang="bash" data-unlink>sudo cp 99mozillateamppa /etc/apt/preferences.d</pre> <p>を実行してあげるといいです。</p> <h3 id="ステップ全体での-99mozillateamppa-の適用のさせ方">ステップ全体での <code>99mozillateamppa</code> の適用のさせ方</h3> <p> ステップ全体としては以下のような流れで実行していきます<a href="#f-23e95ed3" id="fn-23e95ed3" name="fn-23e95ed3" title="シェルスクリプトで用意してあげてもいいです">*1</a>。</p> <pre class="code bash" data-lang="bash" data-unlink>sudo snap remove --purge firefox sudo apt remove --autoremove firefox sudo add-apt-repository ppa:mozillateam/ppa sudo cp path/to/99mozillateamppa /etc/apt/preferences.d sudo apt update sudo apt install -y firefox</pre> <div class="footnote"> <p class="footnote"><a href="#fn-23e95ed3" id="f-23e95ed3" name="f-23e95ed3" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">シェルスクリプトで用意してあげてもいいです</span></p> </div> gregminster gh secret set コマンドを submodule 内で実行すると submodule のリポジトリに登録されてしまうので注意 hatenablog://entry/6801883189064086578 2024-01-19T05:00:00+09:00 2024-01-19T05:00:00+09:00 結論 標題のとおりです*1。 具体例 REPO/sub 配下が submodule だとして、たとえば以下のように gh secret set したとします。 $ cd sub $ gh secret set HOGE< fuga.txt ✓ Set Actions secret HOGE for username/sub 以上のように submodule の方のリポジトリに登録されてしまいます。 正しく登録するには以下のようにします。cd してはいけません。 $ gh secret set HOGE< sub/fuga.txt ✓ Set Actions secret HOGE for us… <h1 id="結論">結論</h1> <p>標題のとおりです<a href="#f-92a01114" id="fn-92a01114" name="fn-92a01114" title="あたりまえのことなのですが小一時間ハマりました">*1</a>。</p> <h1 id="具体例">具体例</h1> <p><code>REPO/sub</code> 配下が submodule だとして、たとえば以下のように <code>gh secret set</code> したとします。</p> <pre class="code bash" data-lang="bash" data-unlink>$ cd sub $ gh secret set HOGE&lt; fuga.txt ✓ Set Actions secret HOGE for username/sub </pre> <p>以上のように submodule の方のリポジトリに登録されてしまいます。</p> <p>正しく登録するには以下のようにします。<code>cd</code> してはいけません。</p> <pre class="code bash" data-lang="bash" data-unlink>$ gh secret set HOGE&lt; sub/fuga.txt ✓ Set Actions secret HOGE for username/REPO</pre> <div class="footnote"> <p class="footnote"><a href="#fn-92a01114" id="f-92a01114" name="f-92a01114" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">あたりまえのことなのですが小一時間ハマりました</span></p> </div> gregminster 「しゃべりすぎGAMER」にて 百英雄伝 の話題が hatenablog://entry/6801883189075584563 2024-01-16T20:19:30+09:00 2024-01-16T20:23:34+09:00 28:17ぐらいから32:44ぐらいまで www.youtube.com <p>28:17ぐらいから32:44ぐらいまで</p> <p><iframe width="560" height="315" src="https://www.youtube.com/embed/hvELC6HMbU4?start=1697&feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="JRPGの現在地を語る!「FF7リバース」や『龍が如く8』などに期待を込めて:#379 しゃべりすぎGAMER"></iframe><cite class="hatena-citation"><a href="https://www.youtube.com/watch?v=hvELC6HMbU4&t=1697s">www.youtube.com</a></cite></p> gregminster Rails でテスト環境の migration が更新されない場合は schema.rb がそのままの可能性が高い hatenablog://entry/6801883189063989831 2024-01-12T05:00:00+09:00 2024-01-12T05:00:01+09:00 結論 標題通りです。 マイグレーションのコードをテストと同時に書いていた際にハマりました。直接コマンドで db:migrate(:reset) すると schema.rb を見に行き、schema.rb の更新作業が走っていない場合には例えば UNIQUE制約 などが変更されません。 DBが空っぽの状態から、一定のデータを CSVインポート によって投入したいという状況のとき、DB を空っぽにする作業を行わないと既存レコードが存在してしまってエラーになるし、かといって bin/rails db:migrate:reset みたいなのを実行する行を挿入すると冒頭の現象にハマります。 <h1 id="結論">結論</h1> <p>標題通りです。</p> <p>マイグレーションのコードをテストと同時に書いていた際にハマりました。直接コマンドで <code>db:migrate(:reset)</code> すると <code>schema.rb</code> を見に行き、<code>schema.rb</code> の更新作業が走っていない場合には例えば UNIQUE制約 などが変更されません。</p> <p>DBが空っぽの状態から、一定のデータを CSVインポート によって投入したいという状況のとき、DB を空っぽにする作業を行わないと既存レコードが存在してしまってエラーになるし、かといって <code>bin/rails db:migrate:reset</code> みたいなのを実行する行を挿入すると冒頭の現象にハマります。</p> gregminster Prettier + VSCode でエラーが出て自動フォーマットできないとき hatenablog://entry/6801883189063168158 2024-01-05T04:00:00+09:00 2024-01-05T04:00:00+09:00 gyazo.com 現象 github.com 結論(これで解決した) プロジェクトに Prettier を入れて Prettier Path には ./node_modules/prettier を指定する。 それまでは nodenv を用いた上でグローバルに入れていた*1が、プロジェクト配下に入れることで解決した。 *1:良くない <p><a href="https://i.gyazo.com/67f106b419d3fcaee94375978ceb9464.png" title=""><img alt="" class="http-image" src="https://i.gyazo.com/67f106b419d3fcaee94375978ceb9464.png" /></a><cite class="hatena-citation"><a href="https://gyazo.com/67f106b419d3fcaee94375978ceb9464">gyazo.com</a></cite></p> <h1 id="現象">現象</h1> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fprettier%2Fprettier-vscode%2Fissues%2F3071" title="Prettier does not format documents in latest Prettier + VS code versions · Issue #3071 · prettier/prettier-vscode" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/prettier/prettier-vscode/issues/3071">github.com</a></cite></p> <h1 id="結論これで解決した">結論(これで解決した)</h1> <p>プロジェクトに Prettier を入れて <code>Prettier Path</code> には <code>./node_modules/prettier</code> を指定する。</p> <p>それまでは nodenv を用いた上でグローバルに入れていた<a href="#f-85af4ddd" id="fn-85af4ddd" name="fn-85af4ddd" title="良くない">*1</a>が、プロジェクト配下に入れることで解決した。</p> <div class="footnote"> <p class="footnote"><a href="#fn-85af4ddd" id="f-85af4ddd" name="f-85af4ddd" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">良くない</span></p> </div> gregminster Cloudflare Pages の初回 GitHub 連携が 8000000 エラーになるときの対処法 hatenablog://entry/6801883189063078755 2023-12-29T04:00:00+09:00 2023-12-29T04:00:00+09:00 結論 GitHub 側で一度 Cloudflare のアプリを削除してから再インストールする。 <h1 id="結論">結論</h1> <p>GitHub 側で一度 Cloudflare のアプリを削除してから再インストールする。</p> gregminster MeCab の辞書をビルドするときに文字コードが euc-jp になってしまう場合の対処方法 hatenablog://entry/6801883189059530547 2023-12-22T05:30:00+09:00 2023-12-22T05:30:02+09:00 結論 mecab-ipadic-2.7.0-20070801 を --with-charset=utf8 のオプション付きでビルドする。 $ ./configure --with-charset=utf8 Natto で確認する 期待通りの挙動になっているかを Natto で確認します。 > require 'natto' > nm = Natto::MeCab.new => #<Natto::MeCab:0x00007f2546c63280 @model=#<FFI::Pointer address=0x0000561020b78620>, @tagger=#<FFI::Pointer ad… <h1 id="結論">結論</h1> <p><code>mecab-ipadic-2.7.0-20070801</code> を <code>--with-charset=utf8</code> のオプション付きでビルドする。</p> <pre class="code bash" data-lang="bash" data-unlink>$ ./configure --with-charset=utf8</pre> <h1 id="Natto-で確認する">Natto で確認する</h1> <p>期待通りの挙動になっているかを <a href="https://github.com/buruzaemon/natto">Natto</a> で確認します。</p> <pre class="code lang-ruby" data-lang="ruby" data-unlink>&gt; <span class="synPreProc">require</span> <span class="synSpecial">'</span><span class="synConstant">natto</span><span class="synSpecial">'</span> &gt; nm = <span class="synType">Natto</span>::<span class="synType">MeCab</span>.new =&gt; <span class="synComment">#&lt;Natto::MeCab:0x00007f2546c63280 @model=#&lt;FFI::Pointer address=0x0000561020b78620&gt;, @tagger=#&lt;FFI::Pointer address=0x0000561020bb0e20&gt;, @lattice=#&lt;FFI::Pointer address=0x000056101cbcb550&gt;, @libpath=&quot;/usr/local/lib/libmecab.so&quot;, @options={}, @dicts=[#&lt;Natto::DictionaryInfo:0x00007f2546c61980 @filepath=&quot;/usr/local/lib/mecab/dic/ipadic/sys.dic&quot;, charset=utf8, type=0&gt;], @version=0.996&gt;</span> </pre> <p><code>charset=utf8</code> となっているので OK です。ここがたとえば <code>euc-jp</code> になっていると失敗しています。</p> gregminster トライアンドエラーを回すときのコツ hatenablog://entry/6801883189058452147 2023-12-15T05:00:00+09:00 2023-12-15T05:00:05+09:00 自分が意識していることは次のとおりです。 まずは(半)手動で回せるようにする 手動で回すのが面倒になってきたら自動化を考え始める 原則として必要になるまでは自動化は考えない方向で いきなり自動化すると見えなくなってくるものもある 自動化の際はそのコストを考えて、手で回す方が総じてコストが安いならば、単純作業を我慢して手で回す たとえば 1回 につき 30分 かかる試行が 10回 程度で完結する見込みならば、そのために数時間かけて自動化するのは総コスト高になる ただし、自動化の過程で気づきや経験が得られるというメリットがある 自動化が再利用できるタイプのものならば意義はある 小さく部分に分けて回… <p>自分が意識していることは次のとおりです。</p> <ul> <li>まずは(半)手動で回せるようにする</li> <li>手動で回すのが面倒になってきたら自動化を考え始める <ul> <li>原則として必要になるまでは自動化は考えない方向で</li> <li>いきなり自動化すると見えなくなってくるものもある</li> </ul> </li> <li>自動化の際はそのコストを考えて、手で回す方が総じてコストが安いならば、単純作業を我慢して手で回す <ul> <li>たとえば 1回 につき 30分 かかる試行が 10回 程度で完結する見込みならば、そのために数時間かけて自動化するのは総コスト高になる</li> <li>ただし、自動化の過程で気づきや経験が得られるというメリットがある</li> <li>自動化が再利用できるタイプのものならば意義はある</li> </ul> </li> <li>小さく部分に分けて回せるようにする <ul> <li>1回 で 30分 の試行を回すならば、うまく部分を切り取って 5分 で 6回 回し、統合時に 30分 で回せるようにする</li> </ul> </li> </ul> gregminster OBS で「ドック」に「配信情報」が出なくなってしまった場合の対処法 hatenablog://entry/6801883189058074968 2023-12-08T05:00:00+09:00 2023-12-08T05:00:01+09:00 状況 こういう感じで「配信情報」などが出なくなってしまった場合です。 gyazo.com 結論 1. 「設定」→「配信」から「アカウントを切断」し、再接続する。 gyazo.com 2. 再度現れる gyazo.com <h1 id="状況">状況</h1> <p>こういう感じで「配信情報」などが出なくなってしまった場合です。</p> <p><a href="https://i.gyazo.com/0bf6d3606f1a63a140d2fe593e19cd7a.png" title=""><img alt="" class="http-image" src="https://i.gyazo.com/0bf6d3606f1a63a140d2fe593e19cd7a.png" /></a><cite class="hatena-citation"><a href="https://gyazo.com/0bf6d3606f1a63a140d2fe593e19cd7a">gyazo.com</a></cite></p> <h1 id="結論">結論</h1> <h4 id="1-設定配信からアカウントを切断し再接続する">1. 「設定」→「配信」から「アカウントを切断」し、再接続する。</h4> <p><a href="https://i.gyazo.com/ae1bb7861a419c7b3b94c4360c396a89.png" title=""><img alt="" class="http-image" src="https://i.gyazo.com/ae1bb7861a419c7b3b94c4360c396a89.png" /></a><cite class="hatena-citation"><a href="https://gyazo.com/ae1bb7861a419c7b3b94c4360c396a89">gyazo.com</a></cite></p> <h4 id="2-再度現れる">2. 再度現れる</h4> <p><a href="https://i.gyazo.com/2ec1bfc11497a22c3e38e8563ae590c1.png" title=""><img alt="" class="http-image" src="https://i.gyazo.com/2ec1bfc11497a22c3e38e8563ae590c1.png" /></a><cite class="hatena-citation"><a href="https://gyazo.com/2ec1bfc11497a22c3e38e8563ae590c1">gyazo.com</a></cite></p> gregminster マージコミットを必ず生成するか (--no-ff) かどうか hatenablog://entry/6801883189057662898 2023-12-01T05:30:00+09:00 2023-12-01T05:30:00+09:00 結論 チームによる。 自身の現実 様々な場面でどっちも使いたいことがあるので、デフォルト*1を決めて .gitconfig して、そうじゃない場合にはオプションを使うというふうにしています。 *1:--no-ff <h1 id="結論">結論</h1> <p>チームによる。</p> <h1 id="自身の現実">自身の現実</h1> <p>様々な場面でどっちも使いたいことがあるので、デフォルト<a href="#f-bf2c5153" id="fn-bf2c5153" name="fn-bf2c5153" title="--no-ff">*1</a>を決めて <code>.gitconfig</code> して、そうじゃない場合にはオプションを使うというふうにしています。</p> <div class="footnote"> <p class="footnote"><a href="#fn-bf2c5153" id="f-bf2c5153" name="f-bf2c5153" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">--no-ff</span></p> </div> gregminster IFTTT の Twitter (X) 連携にて一部の記法が使用不可に hatenablog://entry/820878482970427268 2023-11-27T03:30:00+09:00 2023-11-30T12:49:47+09:00 結論 Twitter changes to search formatting <h1 id="結論">結論</h1> <p><a href="https://help.ifttt.com/hc/en-us/articles/18823795204763">Twitter changes to search formatting</a></p> gregminster Ruby で Time.parse しようとすると undefined method `parse' for Time:Class のエラーが出るとき hatenablog://entry/820878482964903097 2023-11-24T06:30:00+09:00 2023-11-24T06:30:00+09:00 結論 require 'time' する。 <h1 id="結論">結論</h1> <p><code>require 'time'</code> する。</p> gregminster GAS で createFile(BLOB) に対してファイル名を付与する方法 hatenablog://entry/820878482955954847 2023-11-21T04:00:00+09:00 2023-11-21T04:00:02+09:00 結論 const createdFile = currentFolder.createFile(BLOB) createdFile.setName('HOGE.JPG') 補足 createFile(BLOB) の戻り値がファイルオブジェクトであることを利用します 作ってから直後にファイル名を変更する、という方法です <h1 id="結論">結論</h1> <pre class="code lang-javascript" data-lang="javascript" data-unlink><span class="synStatement">const</span> createdFile = currentFolder.createFile(BLOB) createdFile.setName(<span class="synConstant">'HOGE.JPG'</span>) </pre> <h1 id="補足">補足</h1> <ul> <li><code>createFile(BLOB)</code> の戻り値がファイルオブジェクトであることを利用します</li> <li>作ってから直後にファイル名を変更する、という方法です</li> </ul> gregminster Ubuntu Desktop を使って Desktop ログイン をしていると CUI で X11 を Forwarding できない hatenablog://entry/820878482950472869 2023-11-18T04:00:00+09:00 2023-11-18T04:00:00+09:00 結論(どうするか) デスクトップモードをオフにする。 $ sudo systemctl set-default multi-user.target 背景 Authorization required, but no authorization protocol specified とか xhost: unable to open display "" のいつものエラーが出て混乱するが、よく考えたらデスクトップモードを使っていたよな*1ってことで解決。 参考 bitto.jp *1:安い Intel の ボックスPC に Ubuntu を入れている <h1 id="結論どうするか">結論(どうするか)</h1> <p>デスクトップモードをオフにする。</p> <pre class="code bash" data-lang="bash" data-unlink>$ sudo systemctl set-default multi-user.target </pre> <h1 id="背景">背景</h1> <p><code>Authorization required, but no authorization protocol specified</code> とか <code>xhost: unable to open display ""</code> のいつものエラーが出て混乱するが、よく考えたらデスクトップモードを使っていたよな<a href="#f-b846dacb" id="fn-b846dacb" name="fn-b846dacb" title="安い Intel の ボックスPC に Ubuntu を入れている">*1</a>ってことで解決。</p> <h1 id="参考">参考</h1> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fbitto.jp%2Fubuntu-multi-user%2F" title="UbuntuのGUI(デスクトップ)をオフにする" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://bitto.jp/ubuntu-multi-user/">bitto.jp</a></cite></p> <div class="footnote"> <p class="footnote"><a href="#fn-b846dacb" id="f-b846dacb" name="f-b846dacb" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">安い Intel の ボックスPC に Ubuntu を入れている</span></p> </div> gregminster Heroku でデプロイ時にシェルスクリプトを実行するためには .profile を作って書く方法もある(問題点あり) hatenablog://entry/820878482945216042 2023-11-15T04:30:00+09:00 2023-11-15T04:30:00+09:00 結論 標題通りです。 Procfile に release タグで書いてもうまくいかないときもあります。これはずばり「リリースフェーズ中のファイルシステムの変更はアプリの Dyno formation にデプロイされない」ということが理由です*1。 この場合は .procfile に書くという逃げ道があります。 問題点 .profile なので、たとえば $ heroku run bash でシェルに入るときに毎回実行されてしまう。したがって、内容は冪等になるものであり、かつ、時間がかからないものにしないといけない。 「あなたが今やっていることはちょっと変なことだよ」ということの証拠だと思うの… <h1 id="結論">結論</h1> <p>標題通りです。</p> <p><code>Procfile</code> に <code>release</code> タグで書いてもうまくいかないときもあります。これはずばり「<a href="https://devcenter.heroku.com/ja/articles/release-phase#design-considerations">リリースフェーズ中のファイルシステムの変更はアプリの Dyno formation にデプロイされない</a>」ということが理由です<a href="#f-c0f03f50" id="fn-c0f03f50" name="fn-c0f03f50" title="期待されているリリースフェイズでの挙動は、アセットのアップロードやデータベースの構築など、外部のリソースだけに関わるものでしょう">*1</a>。</p> <p>この場合は <code>.procfile</code> に書くという逃げ道があります。</p> <h1 id="問題点">問題点</h1> <p><code>.profile</code> なので、たとえば <code>$ heroku run bash</code> でシェルに入るときに毎回実行されてしまう。したがって、内容は冪等になるものであり、かつ、時間がかからないものにしないといけない。</p> <p>「あなたが今やっていることはちょっと変なことだよ」ということの証拠だと思うので、とりあえずこじんまりとまとめるべき。</p> <h1 id="補足">補足</h1> <ul> <li>実際問題として何に困ってこの方法にたどり着いたかというと、PostgreSQL に接続するために証明書がいるのですが、それは「ファイルのパス指定」でしか対象を指定できないことです<a href="#f-db226c3f" id="fn-db226c3f" name="fn-db226c3f" title="生テキストなら環境変数などが使えた">*2</a></li> <li><code>.profile</code> の実行と <code>Procfile</code> の <code>release:</code> の実行順序については、<code>Procfile</code> の方が先です<a href="#f-80120aed" id="fn-80120aed" name="fn-80120aed" title="したがって、.profile で生成したファイルを用いて Procfile で何かをすることはできない">*3</a> <ul> <li>このため、いろいろと辛みがあることが存在する</li> </ul> </li> </ul> <h1 id="ドキュメント">ドキュメント</h1> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fdevcenter.heroku.com%2Farticles%2Fdynos%23the-profile-file" title="Dynos and the Dyno Manager | Heroku Dev Center" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://devcenter.heroku.com/articles/dynos#the-profile-file">devcenter.heroku.com</a></cite></p> <div class="footnote"> <p class="footnote"><a href="#fn-c0f03f50" id="f-c0f03f50" name="f-c0f03f50" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">期待されているリリースフェイズでの挙動は、アセットのアップロードやデータベースの構築など、外部のリソースだけに関わるものでしょう</span></p> <p class="footnote"><a href="#fn-db226c3f" id="f-db226c3f" name="f-db226c3f" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">生テキストなら環境変数などが使えた</span></p> <p class="footnote"><a href="#fn-80120aed" id="f-80120aed" name="f-80120aed" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">したがって、.profile で生成したファイルを用いて Procfile で何かをすることはできない</span></p> </div> gregminster Squid で「通常はBasic認証をかけるが特定の IPアドレス からは許可する」設定を書く方法 hatenablog://entry/820878482943568351 2023-11-12T03:30:00+09:00 2023-11-12T03:30:00+09:00 結論 他のソフトウェアの設定書式と同様に「優先的な設定を上に書く」とよい。 具体例 OK な書き方 foobar の ACL である時点で allow されるので、OK。 # 特定の ACL からは許可する http_access allow foobar # 認証 auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/fugapass acl password proxy_auth REQUIRED http_access allow password NG な書き方 http_access allow pass… <h1 id="結論">結論</h1> <p>他のソフトウェアの設定書式と同様に「優先的な設定を上に書く」とよい。</p> <h1 id="具体例">具体例</h1> <h3 id="OK-な書き方">OK な書き方</h3> <p><code>foobar</code> の ACL である時点で <code>allow</code> されるので、OK。</p> <pre class="code lang-conf" data-lang="conf" data-unlink><span class="synComment"># 特定の ACL からは許可する</span> http_access allow foobar <span class="synComment"># 認証</span> auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/fugapass acl password proxy_auth REQUIRED http_access allow password </pre> <h3 id="NG-な書き方">NG な書き方</h3> <p><code>http_access allow password</code> が上にあるので、必ず認証が求められてしまう。</p> <pre class="code lang-conf" data-lang="conf" data-unlink><span class="synComment"># 認証</span> auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/fugapass acl password proxy_auth REQUIRED http_access allow password <span class="synComment"># 特定の ACL からは許可する</span> http_access allow foobar </pre> gregminster Ruby で Google::Apis::DriveV3 を用いて Google Drive のファイルを操作する方法 hatenablog://entry/820878482943123703 2023-11-09T06:30:00+09:00 2023-11-09T06:30:00+09:00 前提条件 サービスアカウントを用いて認証を行うとします 使う gem google-api-client google-apis-sheets_v4 でもいいですが、名前が適切な方が誰からも分かりやすいので google-api-client がよいと思います 注意事項 当該ドライブ(フォルダ等)に、サービスアカウントによるアクセス権限を予め付与しておくこと*1 認証コードでは require 'google/apis/drive_v3' を明示的に書くこと*2 具体的方法 認証 いつものやりかたです。スプレッドシートなどと同じです。 以下は概念的なコードですです。 require 'goog… <h1 id="前提条件">前提条件</h1> <ul> <li>サービスアカウントを用いて認証を行うとします</li> </ul> <h1 id="使う-gem">使う gem</h1> <ul> <li><a href="https://github.com/gimite/google-drive-ruby">google-api-client</a> <ul> <li><code>google-apis-sheets_v4</code> でもいいですが、名前が適切な方が誰からも分かりやすいので <code>google-api-client</code> がよいと思います</li> </ul> </li> </ul> <h1 id="注意事項">注意事項</h1> <ul> <li>当該ドライブ(フォルダ等)に、サービスアカウントによるアクセス権限を予め付与しておくこと<a href="#f-d6c4cab7" id="fn-d6c4cab7" name="fn-d6c4cab7" title="忘れやすい">*1</a></li> <li>認証コードでは <code>require 'google/apis/drive_v3'</code> を明示的に書くこと<a href="#f-4b09759d" id="fn-4b09759d" name="fn-4b09759d" title="Rails だとしても">*2</a></li> </ul> <h1 id="具体的方法">具体的方法</h1> <h3 id="認証">認証</h3> <p>いつものやりかたです。スプレッドシートなどと同じです。</p> <p>以下は概念的なコードですです。</p> <pre class="code lang-ruby" data-lang="ruby" data-unlink><span class="synPreProc">require</span> <span class="synSpecial">'</span><span class="synConstant">google/apis/drive_v3</span><span class="synSpecial">'</span> <span class="synComment"># 重要</span> <span class="synPreProc">def</span> <span class="synIdentifier">create_api</span> authorizer = <span class="synType">Google</span>::<span class="synType">Auth</span>::<span class="synType">ServiceAccountCredentials</span>.make_creds( <span class="synConstant">json_key_io</span>: <span class="synType">File</span>.open(<span class="synSpecial">'</span><span class="synConstant">/path/to/credentials.json</span><span class="synSpecial">'</span>), <span class="synConstant">scope</span>: <span class="synSpecial">%w[</span> <span class="synConstant"> https://www.googleapis.com/auth/drive</span> <span class="synConstant"> https://www.googleapis.com/auth/drive.file</span> <span class="synConstant"> </span><span class="synSpecial">]</span> ) authorizer.fetch_access_token! <span class="synComment"># https://googleapis.dev/ruby/google-api-client/latest/Google/Apis/DriveV3/DriveService.html</span> api = <span class="synType">Google</span>::<span class="synType">Apis</span>::<span class="synType">DriveV3</span>::<span class="synType">DriveService</span>.new api.authorization = authorizer api <span class="synPreProc">end</span> </pre> <h3 id="特定のフォルダ直下のファイルやフォルダを取得する">特定のフォルダ直下のファイルやフォルダを取得する</h3> <p>ここが最大のハマりポイントです。</p> <p>結論から書くと<a href="https://stackoverflow.com/questions/70749061/google-drive-api-error-message-shared-drive-not-found-xyz">「 <code>drive_id</code> を親として、その親の中のファイルやフォルダを『検索する』」方法により取得</a>します。</p> <pre class="code lang-ruby" data-lang="ruby" data-unlink>api = create_api listed_files = api.list_files(<span class="synConstant">q</span>: <span class="synSpecial">&quot;</span><span class="synConstant">'ドライブID' in parents</span><span class="synSpecial">&quot;</span>) </pre> <p>これで Google::Apis::DriveV3::FileList のオブジェクトが得られます。その他の実行時オプションは都合に応じて用います。ただし、corpora を指定してしまうとなぜか drive_id が正しくても認証できません<a href="#f-7ba5bcf5" id="fn-7ba5bcf5" name="fn-7ba5bcf5" title="ここが最大のハマりポイント。サービスアカウントだからかも">*3</a>。</p> <p>ここさえできれば後は大丈夫でしょう。</p> <h3 id="listed_files-の個々の中身を調べる">listed_files の個々の中身を調べる</h3> <pre class="code lang-ruby" data-lang="ruby" data-unlink>file_objects = listed_files.files </pre> <h3 id="ファイルの-mime_type-を調べる">ファイルの mime_type を調べる</h3> <p>上記の <code>file_objects</code> の各要素である <code>file_object</code> には <code>mime_type</code> が定義されています。この <code>mime_type</code> により、そのオブジェクトがフォルダなのかファイルなのかを判別できます<a href="#f-4f15ed35" id="fn-4f15ed35" name="fn-4f15ed35" title="#kind というのがあるんですが、これは全て drive#file なので騙されてはいけません">*4</a>。</p> <p><code>mime_type</code> には以下のような種類があります。この値で分岐を書けば、フォルダの中のフォルダを掘るようなコードはすぐ書けるでしょう<a href="#f-93686c62" id="fn-93686c62" name="fn-93686c62" title="先ほど書いた、q: &quot;'ドライブID' in parents&quot; の「ドライブID」を「オブジェクトID」に変更すればいい">*5</a>。</p> <ul> <li><code>application/vnd.google-apps.folder</code></li> <li><code>application/vnd.google-apps.spreadsheet</code></li> <li><code>application/vnd.google-apps.document</code></li> <li><code>image/png</code></li> <li><code>image/jpeg</code></li> </ul> <h3 id="ファイルを作成アップロードする">ファイルを作成(アップロード)する</h3> <p>以下のように書きます。オプションは他にもあるので後述のドキュメントを見ます。</p> <pre class="code lang-ruby" data-lang="ruby" data-unlink>api.create_file( { <span class="synConstant">name</span>: <span class="synSpecial">&quot;</span><span class="synConstant">file.txt</span><span class="synSpecial">&quot;</span>, <span class="synConstant">parents</span>: [upload_folder_id], <span class="synComment"># 配列であることに注意</span> }, <span class="synConstant">upload_source</span>: <span class="synSpecial">'</span><span class="synConstant">/path/to/sample.txt</span><span class="synSpecial">'</span> ) </pre> <h3 id="ファイルをダウンロードする">ファイルをダウンロードする</h3> <pre class="code lang-ruby" data-lang="ruby" data-unlink>api.get_file(file_id, <span class="synConstant">download_dest</span>: <span class="synSpecial">'</span><span class="synConstant">/tmp/foobar</span><span class="synSpecial">'</span>) </pre> <h1 id="重要ドキュメント">重要ドキュメント</h1> <p>以下のドキュメントは超重要です。これらを見れば全て書いてあります。</p> <h3 id="GoogleApisDriveV3DriveService">Google::Apis::DriveV3::DriveService</h3> <p>これが <code>create_api</code> で作られるインスタンスです。これが全てのベースです。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgoogleapis.dev%2Fruby%2Fgoogle-api-client%2Flatest%2FGoogle%2FApis%2FDriveV3%2FDriveService.html" title="Class: Google::Apis::DriveV3::DriveService — Documentation by YARD 0.9.26" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://googleapis.dev/ruby/google-api-client/latest/Google/Apis/DriveV3/DriveService.html">googleapis.dev</a></cite></p> <h3 id="GoogleApisDriveV3FileList">Google::Apis::DriveV3::FileList</h3> <p><code>list_files</code> したときの戻り値のインスタンスが属するクラスです。</p> <p>中身は次項の <code>Class: Google::Apis::DriveV3::FileList</code> のインスタンスが詰め込まれた配列になっています。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgoogleapis.dev%2Fruby%2Fgoogle-api-client%2Flatest%2FGoogle%2FApis%2FDriveV3%2FFileList.html" title="Class: Google::Apis::DriveV3::FileList — Documentation by YARD 0.9.26" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://googleapis.dev/ruby/google-api-client/latest/Google/Apis/DriveV3/FileList.html">googleapis.dev</a></cite></p> <h3 id="GoogleApisDriveV3File">Google::Apis::DriveV3::File</h3> <p><code>Class: Google::Apis::DriveV3::FileList</code> の中に詰め込まれている配列の各要素です。</p> <p>たとえば以下のようなオブジェクトです。ここまで取れればあとはやりたい放題です。</p> <pre class="code lang-ruby" data-lang="ruby" data-unlink> <span class="synComment">#&lt;Google::Apis::DriveV3::File:0x00007f957321c630</span> <span class="synIdentifier">@id</span>=<span class="synSpecial">&quot;</span><span class="synConstant">1234567890</span><span class="synSpecial">&quot;</span>, <span class="synIdentifier">@kind</span>=<span class="synSpecial">&quot;</span><span class="synConstant">drive#file</span><span class="synSpecial">&quot;</span>, <span class="synIdentifier">@mime_type</span>=<span class="synSpecial">&quot;</span><span class="synConstant">image/jpeg</span><span class="synSpecial">&quot;</span>, <span class="synIdentifier">@name</span>=<span class="synSpecial">&quot;</span><span class="synConstant">my_photo.jpg</span><span class="synSpecial">&quot;</span>&gt;, </pre> <h3 id="ファイル検索クエリ書式">ファイル検索クエリ書式</h3> <p>ファイルを検索する際のクエリの書き方の説明です。これを見ないとファイル検索(絞り込み)が満足にできないので、一読しておいたほうがいいです。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fdevelopers.google.com%2Fdrive%2Fapi%2Fguides%2Fsearch-files%3Fhl%3Dja" title="ファイルやフォルダを検索する  |  Google Drive  |  Google for Developers" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://developers.google.com/drive/api/guides/search-files?hl=ja">developers.google.com</a></cite></p> <h1 id="感想と結論">感想と結論</h1> <ul> <li>上記のことがわかっていればだいたいのことはできる</li> <li>しかし、コードがごちゃごちゃしてしまいそうだ</li> <li><a href="https://github.com/gimite/google-drive-ruby">ラッパー gem</a> を使いたくなるのも分かる。 <ul> <li>が、だいぶメンテされていないようだし、共有フォルダ・共有ファイルを扱うにはこっちしかないっぽいと思うので、頑張ってこっちで書いたほうがいいと思う</li> </ul> </li> <li>ここまで面倒だと GAS でやったほうが楽なことが多いし、実際そうしている <ul> <li>GAS はドキュメントも多いし Clasp を使えばまあまあ楽</li> </ul> </li> </ul> <div class="footnote"> <p class="footnote"><a href="#fn-d6c4cab7" id="f-d6c4cab7" name="f-d6c4cab7" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">忘れやすい</span></p> <p class="footnote"><a href="#fn-4b09759d" id="f-4b09759d" name="f-4b09759d" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">Rails だとしても</span></p> <p class="footnote"><a href="#fn-7ba5bcf5" id="f-7ba5bcf5" name="f-7ba5bcf5" class="footnote-number">*3</a><span class="footnote-delimiter">:</span><span class="footnote-text">ここが最大のハマりポイント。サービスアカウントだからかも</span></p> <p class="footnote"><a href="#fn-4f15ed35" id="f-4f15ed35" name="f-4f15ed35" class="footnote-number">*4</a><span class="footnote-delimiter">:</span><span class="footnote-text">#kind というのがあるんですが、これは全て drive#file なので騙されてはいけません</span></p> <p class="footnote"><a href="#fn-93686c62" id="f-93686c62" name="f-93686c62" class="footnote-number">*5</a><span class="footnote-delimiter">:</span><span class="footnote-text">先ほど書いた、q: "'ドライブID' in parents" の「ドライブID」を「オブジェクトID」に変更すればいい</span></p> </div> gregminster VS Code で RuboCop の formatOnSave を Gemfile に対しても有効にする方法 hatenablog://entry/820878482943273557 2023-11-09T04:00:00+09:00 2023-11-09T04:00:00+09:00 結論 settings.json に以下を書き加える。 "files.associations": { "**/Gemfile": "ruby" }, 背景 Gemfile は Ruby のファイルとはみなされていないのでフォーマッタが働かない。明示的に ruby だよ、と指定することで、Ruby の書式*1 に則ったフォーマッタが発動するようになる。 *1:RuboCop <h1 id="結論">結論</h1> <p><code>settings.json</code> に以下を書き加える。</p> <pre class="code lang-json" data-lang="json" data-unlink> &quot;<span class="synStatement">files.associations</span>&quot;: <span class="synSpecial">{</span> &quot;<span class="synStatement">**/Gemfile</span>&quot;: &quot;<span class="synConstant">ruby</span>&quot; <span class="synSpecial">}</span>, </pre> <h1 id="背景">背景</h1> <p><code>Gemfile</code> は Ruby のファイルとはみなされていないのでフォーマッタが働かない。明示的に <code>ruby</code> だよ、と指定することで、Ruby の書式<a href="#f-6604f817" id="fn-6604f817" name="fn-6604f817" title="RuboCop">*1</a> に則ったフォーマッタが発動するようになる。</p> <div class="footnote"> <p class="footnote"><a href="#fn-6604f817" id="f-6604f817" name="f-6604f817" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">RuboCop</span></p> </div> gregminster ImageMagick の magick コマンドで画像を連結する方法 hatenablog://entry/820878482943059916 2023-11-06T04:00:00+09:00 2023-11-06T04:00:00+09:00 結論 縦に連結する場合 $ magick A.png B.png -append A_B.png 横に連結する場合 $ magick X.png Y.png +append X_Y.png 補足 連結する画像の枚数は 3枚以上 でも問題ありません。 <h1 id="結論">結論</h1> <h4 id="縦に連結する場合">縦に連結する場合</h4> <pre class="code bash" data-lang="bash" data-unlink>$ magick A.png B.png -append A_B.png</pre> <h4 id="横に連結する場合">横に連結する場合</h4> <pre class="code bash" data-lang="bash" data-unlink>$ magick X.png Y.png +append X_Y.png</pre> <h1 id="補足">補足</h1> <p>連結する画像の枚数は 3枚以上 でも問題ありません。</p> gregminster Jotform を WordPress に埋め込む場合は hatenablog://entry/820878482942959663 2023-11-03T05:30:00+09:00 2023-11-03T05:30:00+09:00 結論 IFRAME を使う。 IFRAME を使わないと、縦が収まらないでスクロールバーが出てしまうから。 gyazo.com だめな方法 以下の 2つ はいずれもダメです。 1. 「プラットフォーム」で WordPress を選ぶ gyazo.com 2. WordPress のプラグインを使って専用書式で埋め込む 内部的には 1. と同じです。 gyazo.com 余談 以下のような ヘルプページ や Q&A がありますが、いずれも誤っています。 www.jotform.com www.jotform.com <h1 id="結論">結論</h1> <p>IFRAME を使う。</p> <p>IFRAME を使わないと、縦が収まらないでスクロールバーが出てしまうから。</p> <p><a href="https://i.gyazo.com/7f6d3f4095c16311cef741c4c67a4ae2.png" title=""><img alt="" class="http-image" src="https://i.gyazo.com/7f6d3f4095c16311cef741c4c67a4ae2.png" /></a><cite class="hatena-citation"><a href="https://gyazo.com/7f6d3f4095c16311cef741c4c67a4ae2">gyazo.com</a></cite></p> <h1 id="だめな方法">だめな方法</h1> <p>以下の 2つ はいずれもダメです。</p> <h4 id="1-プラットフォームで-WordPress-を選ぶ">1. 「プラットフォーム」で WordPress を選ぶ</h4> <p><a href="https://i.gyazo.com/f035024450e16d1d917611c968ff11b7.png" title=""><img alt="" class="http-image" src="https://i.gyazo.com/f035024450e16d1d917611c968ff11b7.png" /></a><cite class="hatena-citation"><a href="https://gyazo.com/f035024450e16d1d917611c968ff11b7">gyazo.com</a></cite></p> <h4 id="2-WordPress-のプラグインを使って専用書式で埋め込む">2. WordPress のプラグインを使って専用書式で埋め込む</h4> <p>内部的には 1. と同じです。</p> <p><a href="https://i.gyazo.com/cc8c6e29fc62353cf1655733f4c39c28.png" title=""><img alt="" class="http-image" src="https://i.gyazo.com/cc8c6e29fc62353cf1655733f4c39c28.png" /></a><cite class="hatena-citation"><a href="https://gyazo.com/cc8c6e29fc62353cf1655733f4c39c28">gyazo.com</a></cite></p> <h1 id="余談">余談</h1> <p>以下のような ヘルプページ や Q&amp;A がありますが、いずれも誤っています。</p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.jotform.com%2Fhelp%2F174-embed-jotform-in-wordpress-using-the-embed-form-plugin%2F" title="How to Use the Jotform WordPress Plugin" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://www.jotform.com/help/174-embed-jotform-in-wordpress-using-the-embed-form-plugin/">www.jotform.com</a></cite></p> <p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.jotform.com%2Fanswers%2F3890298-wordpress-embed-adjust-form-height" title="Online Form Builder &amp; Form Creator | Jotform" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://www.jotform.com/answers/3890298-wordpress-embed-adjust-form-height">www.jotform.com</a></cite></p> gregminster Misskey で MinIO をオブジェクトストレージとして扱う方法 hatenablog://entry/820878482942908118 2023-10-31T05:30:00+09:00 2023-10-31T05:30:00+09:00 結論 ポイントがいくつかあります。 Base URL にはバケット名まで書くこと Backet にはやはりバケット名を書くこと Prefix は必須なので何か書くこと*1 Region は MinIO 内で設定している内容と同じにすること gyazo.com *1:書かないと https://example.com/my-bucket//foo.jpg みたいになってしまう <h1 id="結論">結論</h1> <p>ポイントがいくつかあります。</p> <ul> <li><code>Base URL</code> にはバケット名まで書くこと</li> <li><code>Backet</code> にはやはりバケット名を書くこと</li> <li><code>Prefix</code> は必須なので何か書くこと<a href="#f-f82a1257" name="fn-f82a1257" title="書かないと https://example.com/my-bucket//foo.jpg みたいになってしまう">*1</a></li> <li><code>Region</code> は MinIO 内で設定している内容と同じにすること</li> </ul> <p><a href="https://i.gyazo.com/97670f8f689d4b78376e651f17d757d3.png" title=""><img alt="" class="http-image" src="https://i.gyazo.com/97670f8f689d4b78376e651f17d757d3.png" /></a><cite class="hatena-citation"><a href="https://gyazo.com/97670f8f689d4b78376e651f17d757d3">gyazo.com</a></cite></p> <div class="footnote"> <p class="footnote"><a href="#fn-f82a1257" name="f-f82a1257" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">書かないと <a href="https://example.com/my-bucket//foo.jpg">https://example.com/my-bucket//foo.jpg</a> みたいになってしまう</span></p> </div> gregminster Misskey で SES をメールサーバとして用いる方法 hatenablog://entry/820878482942907342 2023-10-28T06:30:00+09:00 2023-10-28T06:30:01+09:00 結論 特に難しいところはないです。 gyazo.com <h1 id="結論">結論</h1> <p>特に難しいところはないです。</p> <p><a href="https://i.gyazo.com/93e57a42fd584e5ff9333f1432889a0d.png" title=""><img alt="" class="http-image" src="https://i.gyazo.com/93e57a42fd584e5ff9333f1432889a0d.png" /></a><cite class="hatena-citation"><a href="https://gyazo.com/93e57a42fd584e5ff9333f1432889a0d">gyazo.com</a></cite></p> gregminster Ubuntu に Misskey をインストールする時にハマったこと hatenablog://entry/820878482942889513 2023-10-25T00:00:00+09:00 2023-10-25T00:01:21+09:00 ※ 2023/06/19 現在の情報です 箇条書きで pnpm が必須 メモリ(スワップ)不足でセットアップスクリプトで落ちる*1 frontend の vite build のところで JavaScript heap out of memory で落ちる packages/frontend build$ vite build │ vite v4.3.9 building for production... │ transforming... │ <--- Last few GCs ---> │ [7199:0x734eef0] 37428 ms: Mark-sweep 468.7 (488.… <p>※ 2023/06/19 現在の情報です</p> <h1 id="箇条書きで">箇条書きで</h1> <ul> <li>pnpm が必須</li> <li>メモリ(スワップ)不足でセットアップスクリプトで落ちる<a href="#f-b5dd72b5" name="fn-b5dd72b5" title="低スペックの VPN で構築したので">*1</a> <ul> <li>frontend の <code>vite build</code> のところで <code>JavaScript heap out of memory</code> で落ちる</li> </ul> </li> </ul> <pre class="code" data-lang="" data-unlink>packages/frontend build$ vite build │ vite v4.3.9 building for production... │ transforming... │ &lt;--- Last few GCs ---&gt; │ [7199:0x734eef0] 37428 ms: Mark-sweep 468.7 (488.3) -&gt; 464.8 (488.8) MB, 678.5 / 0.0 ms (average mu = 0.208, cur │ [7199:0x734eef0] 38127 ms: Mark-sweep 469.0 (488.8) -&gt; 465.1 (489.0) MB, 648.7 / 0.0 ms (average mu = 0.149, cur │ &lt;--- JS stacktrace ---&gt; │ FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory</pre> <ul> <li>対応方法は <a href="https://oss.issuehunt.io/r/syuilo/misskey/issues/6738">こちら</a> にあるとおり、以下の環境変数を指定する <ul> <li><code>NODE_OPTIONS="--max-old-space-size=2048"</code></li> </ul> </li> </ul> <pre class="code bash" data-lang="bash" data-unlink>$ NODE_OPTIONS=&#34;--max-old-space-size=2048&#34; NODE_ENV=production pnpm run build</pre> <ul> <li>これは完全に自分のミスだが、通知を消したいと思って PostgreSQL の user_profile テーブルのレコードを手動で消したら、ユーザも削除された<a href="#f-cf9cb236" name="fn-cf9cb236" title="削除されたというステータスになった">*2</a></li> </ul> <div class="footnote"> <p class="footnote"><a href="#fn-b5dd72b5" name="f-b5dd72b5" class="footnote-number">*1</a><span class="footnote-delimiter">:</span><span class="footnote-text">低スペックの VPN で構築したので</span></p> <p class="footnote"><a href="#fn-cf9cb236" name="f-cf9cb236" class="footnote-number">*2</a><span class="footnote-delimiter">:</span><span class="footnote-text">削除されたというステータスになった</span></p> </div> gregminster