<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Michael Teter</title>
    <description></description>
    <link>https://michaelteter.com/</link>
    <atom:link href="https://michaelteter.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sat, 01 Aug 2026 08:21:00 +0000</pubDate>
    <lastBuildDate>Sat, 01 Aug 2026 08:21:00 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>LiveBook Can&apos;t Connect After Upgrade</title>
        <description>&lt;h2 id=&quot;after-livebook-minor-version-upgrade-cant-connect-to-node&quot;&gt;After LiveBook minor version upgrade, can’t connect to node&lt;/h2&gt;

&lt;p&gt;There was a “small” change in the recent LiveBook project which
may prevent LiveBook from connecting to other nodes.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/livebook-dev/livebook/blob/v0.13.3/CHANGELOG.md?plain=1#L66&quot;&gt;LiveBook Changelog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make your node visible to LiveBook now, you must use
long names.&lt;/p&gt;

&lt;p&gt;Now when starting iex, use ✅ &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--name&lt;/code&gt; instead of ❌ &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--sname&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then in the LiveBook config, specify the full node name such as myproject@mymac.local (for local Mac users).&lt;/p&gt;
</description>
        <pubDate>Wed, 07 Aug 2024 22:18:00 +0000</pubDate>
        <link>https://michaelteter.com/archived-posts/2024/08/07/livebook-cant-connect-after-upgrade.html</link>
        <guid isPermaLink="true">https://michaelteter.com/archived-posts/2024/08/07/livebook-cant-connect-after-upgrade.html</guid>
        
        <category>elixir livebook troubleshooting</category>
        
        
      </item>
    
      <item>
        <title>Macos + Wezterm + VSCode light/dark switcher</title>
        <description>&lt;h2 id=&quot;my-zsh-command-line-approach-to-toggling-my-lightdark-modes-for-the-dev-tools-i-use&quot;&gt;My zsh command-line approach to toggling my light/dark modes for the dev tools I use&lt;/h2&gt;

&lt;p&gt;In my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.zshrc&lt;/code&gt; I have the following:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Function to change WezTerm, VSCode theme, and macOS appearance&lt;/span&gt;
change_themes&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;wezterm_theme&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;vscode_theme&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;macos_mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$3&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;settings_file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/Library/Application Support/Code/User/settings.json&quot;&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;# Update WezTerm theme&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&apos;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;s/^config&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;color_scheme.*&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$/&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;config.color_scheme = &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$wezterm_theme&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&quot;&lt;/span&gt; ~/.config/wezterm/wezterm.lua

  &lt;span class=&quot;c&quot;&gt;# Update VSCode theme&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&apos;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;s/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;workbench&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;colorTheme&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.*&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;workbench.colorTheme&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$vscode_theme&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$settings_file&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;# Update macOS appearance&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$macos_mode&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;dark&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;osascript &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;tell app &quot;System Events&quot; to tell appearance preferences to set dark mode to true&apos;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else
    &lt;/span&gt;osascript &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;tell app &quot;System Events&quot; to tell appearance preferences to set dark mode to false&apos;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;light&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;change_themes &quot;Alabaster&quot; &quot;Default Light+&quot; &quot;light&quot;&apos;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;alias &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;dark&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;change_themes &quot;3024 (dark) (terminal.sexy)&quot; &quot;Panda Syntax&quot; &quot;dark&quot;&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then from any terminal app that’s using zshell and my normal zshell dotfile,&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;light&lt;/code&gt; to change my themes to Light mode.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dark&lt;/code&gt; to change the themes to Dark mode.&lt;/p&gt;

&lt;p&gt;Obviously you can choose your own theme names in the aliases, and you can change the alias names as well. (Be sure to check &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;which dark&lt;/code&gt; or whatever names you choose so you don’t
shadow some other program with that name.)&lt;/p&gt;

&lt;p&gt;Remember to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;source ~/.zshrc&lt;/code&gt; after you change your zshell config file so your changes are recognized in your current shell while setting this up.&lt;/p&gt;
</description>
        <pubDate>Thu, 25 Jul 2024 19:36:00 +0000</pubDate>
        <link>https://michaelteter.com/archived-posts/2024/07/25/custom-light-dark.html</link>
        <guid isPermaLink="true">https://michaelteter.com/archived-posts/2024/07/25/custom-light-dark.html</guid>
        
        <category>macos wezterm vscode configuration</category>
        
        
      </item>
    
      <item>
        <title>When to use halt() in Phoenix Framework</title>
        <description>&lt;h4 id=&quot;tldr&quot;&gt;TLDR;&lt;/h4&gt;

&lt;p&gt;In a pipeline function, call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;halt()&lt;/code&gt; after a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;redirect()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In a controller action, it is not necessary to halt after a redirect.&lt;/p&gt;

&lt;h2 id=&quot;halt---the-confusion&quot;&gt;Halt - The Confusion&lt;/h2&gt;

&lt;p&gt;If you’re a Phoenix beginner like me, you may have seen some code where a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;redirect()&lt;/code&gt; is followed by a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;halt()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The code generated by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix phx.gen.auth&lt;/code&gt; includes a module called &lt;em&gt;UserAuth&lt;/em&gt;, which has the following function defined:&lt;/p&gt;

&lt;div class=&quot;language-elixir highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redirect_if_user_is_authenticated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assigns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:current_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redirect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;to:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;signed_in_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;halt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But you can also find examples where redirect is not followed by halt.  &lt;em&gt;UserSessionController&lt;/em&gt; has the following function:&lt;/p&gt;

&lt;div class=&quot;language-elixir highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;defp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;user&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;email&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;password&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_params&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Accounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_user_by_email_and_password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;put_flash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;UserAuth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log_in_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;put_flash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Invalid email or password&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;put_flash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;160&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redirect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;to:&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;~p&quot;/users/log_in&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;a href=&quot;https://hexdocs.pm/phoenix/Phoenix.Controller.html&quot;&gt;Phoenix Controller docs&lt;/a&gt; docs illustrate a redirect followed by a halt, and the text below their
example states that &lt;a href=&quot;https://hexdocs.pm/plug/1.14.2/Plug.Conn.html#halt/1&quot;&gt;Plug.Conn.halt/1&lt;/a&gt; is “by default imported into controllers”.&lt;/p&gt;

&lt;p&gt;These different examples can make one wonder when and why to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;halt()&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-does-halt-do&quot;&gt;What does halt do?&lt;/h2&gt;

&lt;p&gt;The docs for &lt;a href=&quot;https://hexdocs.pm/plug/1.14.2/Plug.Conn.html#halt/1&quot;&gt;halt(conn)&lt;/a&gt; are brief, saying it “Halts the Plug pipeline by preventing further plugs downstream from being invoked.”&lt;/p&gt;

&lt;p&gt;Phoenix is built around the concept of transforming some input data through a pipeline (a series of pipe stages), resulting in output data which is then returned to the client.  But when circumstances dictate a change in paths (such as with a redirect), then some pipelines need to be stopped.&lt;/p&gt;

&lt;p&gt;Looking in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Router&lt;/code&gt; module, we can see something like this:&lt;/p&gt;

&lt;div class=&quot;language-elixir highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;pipeline&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:browser&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;plug&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:accepts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;html&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;plug&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:fetch_session&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;plug&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:fetch_live_flash&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;plug&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:put_root_layout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;html:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;ExampleWeb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Layouts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;plug&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:protect_from_forgery&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;plug&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:put_secure_browser_headers&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;plug&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:fetch_current_user&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Each of these &lt;em&gt;plugs&lt;/em&gt; gets called in sequence, with the output of the previous
stage being the input of the next stage.  Any one of these stages could decide
that the process needed to deviate or stop based on any number of reasons.&lt;/p&gt;

&lt;p&gt;As we see earlier, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;redirect_if_user_is_authenticated()&lt;/code&gt; branches based on a condition in the current state (which is usually called &lt;a href=&quot;https://hexdocs.pm/plug/1.14.2/Plug.Conn.html#content&quot;&gt;conn&lt;/a&gt;).  In one path, it redirects and halts.  In the other path, it simply returns appropriately so the next stage of the pipeline can be executed.&lt;/p&gt;

&lt;p&gt;In this case, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;halt&lt;/code&gt; is important because it tells Phoenix to stop further processing of this pipeline.  Meanwhile, the redirect will have resulted in another pipeline running, and that pipeline should be the one to determine and return the final data.&lt;/p&gt;

&lt;h2 id=&quot;when-to-use-halt&quot;&gt;When to use halt&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;USE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;halt()&lt;/code&gt; when you need to stop the pipeline from performing any following stages.  This would be in a plug function after a redirect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DON’T USE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since a controller action is the last stage of a pipeline, there is no need to call it within the action (even if you have a redirect).  It is harmless if used at the end of the pipeline, however…&lt;/p&gt;

&lt;h2 id=&quot;why-was-that-confusing&quot;&gt;Why was that confusing?&lt;/h2&gt;

&lt;p&gt;Perhaps it’s just me, but I was confused about this probably mostly because of the previously mentioned line in the controller docs which stated that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;halt&lt;/code&gt; “is by default imported into controllers”.  Why would it be automatically available to controllers if controller actions are the last step of a pipeline?&lt;/p&gt;

&lt;p&gt;The reason is that you may wish to write some function plugs in a controller (similar to Rails’ before filters) which would be run before your actions in that controller.  And your custom plug might wish to stop the current process and redirect to a new one.  Therefore, your plug function would need to use halt.&lt;/p&gt;

&lt;p&gt;I still find the choice to make &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;halt&lt;/code&gt; automatically available in controllers curious, because it implies that there would be so many times you would need it that having it automatically included was a significant convenience.  The implication is that a controller will have more plug functions (with redirects) than actions (which don’t need to halt even if they redirect).  I kind of doubt that’s the reality.&lt;/p&gt;

&lt;p&gt;I would expect controllers to have more actions than plug functions which redirect.  And in that case, I think it would be clearer to make the developer
explicitly import &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;halt/1&lt;/code&gt; when needed.&lt;/p&gt;
</description>
        <pubDate>Sat, 19 Aug 2023 17:06:00 +0000</pubDate>
        <link>https://michaelteter.com/archived-posts/2023/08/19/phoenix-when-to-use-halt.html</link>
        <guid isPermaLink="true">https://michaelteter.com/archived-posts/2023/08/19/phoenix-when-to-use-halt.html</guid>
        
        <category>phoenix phoenix-framework elixir</category>
        
        
      </item>
    
      <item>
        <title>Wordpress (on dynamic IP virtual machine) redirects to old IP</title>
        <description>&lt;h2 id=&quot;problem&quot;&gt;Problem&lt;/h2&gt;

&lt;p&gt;Wordpress on a Virtual Machine keeps redirecting to old IP address&lt;/p&gt;

&lt;p&gt;Using a virtual machine with a dynamic IP bridged to the host machine, and
the host machine connects to various different WIFI networks… I found that
my development Wordpress site on my (virtualbox) VM kept redirecting my web
browser to the old/original IP address the VM had when Wordpress was first
setup.&lt;/p&gt;

&lt;p&gt;I do not yet know the correct solution; surely there is one, but the crude
manual fix is to change the (unfortunately?) hard-coded IP address in the Wordpress
site database.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;

&lt;p&gt;Login to the WP database and check the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql&amp;gt; select * from wp_options where option_name in (&apos;siteurl&apos;, &apos;home&apos;);       
+-----------+-------------+---------------------+----------+
| option_id | option_name | option_value        | autoload |
+-----------+-------------+---------------------+----------+
|         2 | home        | http://192.168.1.17 | yes      |
|         1 | siteurl     | http://192.168.1.17 | yes      |
+-----------+-------------+---------------------+----------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You’ll probably see two rows returned that have the VM’s old IP address.
(What were they thinking with this?)&lt;/p&gt;

&lt;p&gt;Surely this is a dirty fix, and there’s a more correct solution.  But make the
following change:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql&amp;gt; update wp_options set option_value=&apos;http://10.0.1.8&apos; where option_name in (&apos;siteurl&apos;,&apos;home&apos;);
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2  Changed: 2  Warnings: 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With this change, the incorrect redirect should be resolved.&lt;/p&gt;

&lt;p&gt;Naturally you will use whatever IP address in the sql update that your current VM is using; and 
pay attention to your original option_value.  If it was https, then use https in your SQL update.&lt;/p&gt;
</description>
        <pubDate>Sat, 29 Sep 2018 13:42:00 +0000</pubDate>
        <link>https://michaelteter.com/archived-posts/2018/09/29/wordpress-on-dynamic-ip-vm.html</link>
        <guid isPermaLink="true">https://michaelteter.com/archived-posts/2018/09/29/wordpress-on-dynamic-ip-vm.html</guid>
        
        <category>Wordpress dynamic-ip</category>
        
        
      </item>
    
      <item>
        <title>Compiling Elixir Modules In Windows</title>
        <description>&lt;h2 id=&quot;problem&quot;&gt;Problem&lt;/h2&gt;

&lt;p&gt;I wanted to do some Elixir/Phoenix development in Windows 10 (don’t ask why…),
but I couldn’t build my Phoenix app due to a failure building the comeonin module.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;could not compile dependency :comeonin, &quot;mix compile&quot; failed. You can 
recompile this dependency with &quot;mix deps.compile comeonin&quot;, update it with &quot;mix
deps.update comeonin&quot; or clean it with &quot;mix deps.clean comeonin&quot;
** (Mix.Error) Could not find the program `nmake`.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The issue is that even though I had installed the Visual Studio Community 
development tools (which includes nmake), the build tools are not visible
in the path on Powershell.&lt;/p&gt;

&lt;p&gt;Visual Studio does provide a batch file to make those tools visible, but
running that script only makes the tools visible to the (temporary) shell
that the script runs in.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;

&lt;h3 id=&quot;pre-reqs&quot;&gt;Pre-reqs&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Erlang and Elixir (Windows packages) are installed.&lt;/li&gt;
  &lt;li&gt;MS Visual Studio, or the Community version, or the MS build tools, are installed.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;build-tools-paths&quot;&gt;Build Tools Paths&lt;/h3&gt;

&lt;p&gt;From pre-req 2, determine the path to your &lt;em&gt;vcvars64.bat&lt;/em&gt; script.  For me this was&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;powershell-profile&quot;&gt;Powershell Profile&lt;/h3&gt;

&lt;p&gt;Edit the Powershell profile file.  If the file doesn’t exist, create it.  The path is&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:\Users\your_username_here\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Add the following code to the profile&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;function Invoke-CmdScript {
  param(
    [String] $scriptName 
  )
  $cmdLine = &quot;&quot;&quot;$scriptName&quot;&quot; $args &amp;amp; set&quot;
  &amp;amp; $Env:SystemRoot\system32\cmd.exe /c $cmdLine |
  select-string &apos;^([^=]*)=(.*)$&apos; | foreach-object {
    $varName = $_.Matches[0].Groups[1].Value
    $varValue = $_.Matches[0].Groups[2].Value
    set-item Env:$varName $varValue
  }
}

Invoke-CmdScript &quot;C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The function allows you to run a script, the one that makes the build tools visible,
but instead of losing the context after that script ends, the settings are propogated
back to the calling shell (Powershell).&lt;/p&gt;

&lt;p&gt;The profile then uses that Invoke-CmdScript function to call the vcvars64.bat script that we
got from step 2 of the prereqs.&lt;/p&gt;

&lt;p&gt;With this done, you should be able to successfully build/compile Elixir modules within Windows 10.&lt;/p&gt;

</description>
        <pubDate>Fri, 06 Jul 2018 08:55:00 +0000</pubDate>
        <link>https://michaelteter.com/archived-posts/2018/07/06/compiling-Elixir-modules-in-Windows.html</link>
        <guid isPermaLink="true">https://michaelteter.com/archived-posts/2018/07/06/compiling-Elixir-modules-in-Windows.html</guid>
        
        <category>Elixir Windows Powershell</category>
        
        
      </item>
    
      <item>
        <title>Solving the Elixir/Ecto error &apos;undefined function from/2&apos;</title>
        <description>&lt;h2 id=&quot;problem&quot;&gt;Problem&lt;/h2&gt;

&lt;p&gt;In Elixir, when trying to write an Ecto query such as this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;q = from(v in Vol,
    where: v.user_id == ^user.id,
    order_by: [desc: v.inserted_at])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;you may encounter the error:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;undefined function from/2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is a rather difficult error to search for on a search engine, and
more than once over time I have encountered it and had to dig around to find
the solution.&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import Ecto.Query
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Do this before your use of from/2 to include the functions provided by Ecto.Query.&lt;/p&gt;

</description>
        <pubDate>Tue, 06 Mar 2018 03:17:00 +0000</pubDate>
        <link>https://michaelteter.com/archived-posts/2018/03/06/Elixir-Ecto-undefined-function-from.html</link>
        <guid isPermaLink="true">https://michaelteter.com/archived-posts/2018/03/06/Elixir-Ecto-undefined-function-from.html</guid>
        
        <category>Elixir Ecto query from</category>
        
        
      </item>
    
      <item>
        <title>Add Logo to All Images In Folder</title>
        <description>&lt;h1 id=&quot;goal&quot;&gt;Goal&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;We want to superimpose (or overlay) our logo image on top of all images in the current directory.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;These instructions are for &lt;strong&gt;macOS&lt;/strong&gt;, and they assume a basic level of familiarity with entering commands via the &lt;strong&gt;Terminal&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This example shows how to overlay an image (such as a logo) on every image in the current directory.  It works on macOS 10.12, and it probably works in Linux.&lt;/p&gt;

&lt;p&gt;The command will create new images having the original image name with the word &lt;strong&gt;logo_&lt;/strong&gt; prepended.  So &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;an_image.png&lt;/code&gt; is used to create a new file, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;logo_an_image.png&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;pre-requisites&quot;&gt;Pre-requisites&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;You’re on a modern Mac&lt;/li&gt;
  &lt;li&gt;You have &lt;a href=&quot;http://brew.sh/&quot;&gt;HomeBrew&lt;/a&gt; or &lt;a href=&quot;http://www.macports.org/&quot;&gt;MacPorts&lt;/a&gt; installed&lt;/li&gt;
  &lt;li&gt;You have installed &lt;a href=&quot;https://www.imagemagick.org/script/download.php#macosx&quot;&gt;ImageMagick&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;assumptions&quot;&gt;Assumptions&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;You aren’t afraid to use the Terminal&lt;/li&gt;
  &lt;li&gt;You want to process all images in the current directory&lt;/li&gt;
  &lt;li&gt;Your logo image is in a subfolder of this directory called “logo”, and the logo filename is “logo.png”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can change all of the settings and names once you understand the command.&lt;/p&gt;

&lt;h2 id=&quot;risks-and-caveats&quot;&gt;Risks and Caveats&lt;/h2&gt;

&lt;p&gt;If something goes wrong, you could lose data.  It is wise to make regular backups, and it is also wise play with this command first in a test folder with some sample images and logo image.&lt;/p&gt;

&lt;p&gt;This may not be the most efficient or terse solution to the problem, so feel free to share better solutions.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;my_test_folder_with_copies_of_images

find &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-type&lt;/span&gt; f &lt;span class=&quot;nt&quot;&gt;-maxdepth&lt;/span&gt; 1 &lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-iname&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.jpg&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-iname&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.png&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    | &lt;span class=&quot;nb&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;./&apos;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    | &lt;span class=&quot;nb&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;\n&apos;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;\0&apos;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    | xargs &lt;span class=&quot;nt&quot;&gt;-0&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n1&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-I&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    composite &lt;span class=&quot;nt&quot;&gt;-gravity&lt;/span&gt; SouthWest &lt;span class=&quot;nt&quot;&gt;-geometry&lt;/span&gt; +10+10 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        logo/logo.png &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; logo_&lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;what-is-happening&quot;&gt;What is Happening?&lt;/h2&gt;

&lt;p&gt;In short, we get a list of the image files in the current directory, then use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;composite&lt;/code&gt; command from &lt;a href=&quot;https://www.imagemagick.org/script/index.php&quot;&gt;ImageMagick&lt;/a&gt; to add our logo image down near the lower left (&lt;em&gt;SouthWest&lt;/em&gt;) corner of each image from our found list.&lt;/p&gt;

&lt;p&gt;Let’s explore this line by line.  Note that the trailing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\&lt;/code&gt; (backslash) tells the shell to continue the command on the next line.  it’s a good way to break up the long compound command into more readable chunks.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;find . -type f -maxdepth 1 \( -iname &quot;*.jpg&quot; -o -iname &quot;*.png&quot; \) \
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;First, we need to get a list of all image files in the current directory.  The command for that is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.&lt;/code&gt; (dot) means apply the command to the current directory&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-type f&lt;/code&gt; means to only list files (not directories)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-maxdepth 1&lt;/code&gt; means to only look at the current level; don’t go into any sub-directories&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\( -iname &quot;*.jpg&quot; -o -iname &quot;*.png&quot; \)&lt;/code&gt; from the inside out, this says to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-iname&lt;/code&gt; flag to search, case-insensitive, for files ending in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.jpg&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-o&lt;/code&gt; (or) (do another case-insensitive search for files ending in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.png&lt;/code&gt;).  Then we need to wrap that expression with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;)&lt;/code&gt; so they get processed together.  If we don’t do that, the arguments will get parsed from left to right in a way that will not give us the correct result.  Lastly, we have to &lt;em&gt;escape&lt;/em&gt; the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;)&lt;/code&gt; with leading &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\&lt;/code&gt; backslashes so the shell doesn’t try to interpret them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, we &lt;a href=&quot;https://en.wikipedia.org/wiki/Pipeline_(Unix)&quot;&gt;pipe&lt;/a&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|&lt;/code&gt; the output of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sed&lt;/code&gt;, the &lt;em&gt;stream editor&lt;/em&gt;.  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find&lt;/code&gt; is listing the files it finds with a path showing the current directory (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.&lt;/code&gt;) - it looks like this: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./an_image.png&lt;/code&gt;.  However, since we will need to prepend the word &lt;strong&gt;logo_&lt;/strong&gt; to the beginning of our output files, we need to get rid of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./&lt;/code&gt; from each source file name.  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sed&lt;/code&gt; does this for us.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;provide a substitution rule string, denoted by the leading and closing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;&lt;/code&gt; (single quote)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s|a|b|&lt;/code&gt; says “search” for a, replace with b&lt;/li&gt;
  &lt;li&gt;our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a&lt;/code&gt; in this case is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\./&lt;/code&gt; , which is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./&lt;/code&gt; that we want to remove, but we have to &lt;em&gt;escape&lt;/em&gt; that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.&lt;/code&gt; so the shell won’t try to interpret it&lt;/li&gt;
  &lt;li&gt;the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b&lt;/code&gt; (replace) field is empty because we don’t want to replace the search text with anything - we just want to eliminate the search term&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then we pipe the output of the previous step into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tr&lt;/code&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/Tr_(Unix)&quot;&gt;translate&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Mon, 06 Mar 2017 01:07:00 +0000</pubDate>
        <link>https://michaelteter.com/archived-posts/2017/03/06/add-logo-to-all-images-in-folder.html</link>
        <guid isPermaLink="true">https://michaelteter.com/archived-posts/2017/03/06/add-logo-to-all-images-in-folder.html</guid>
        
        <category>shell terminal imagemagick batch-processing</category>
        
        
      </item>
    
      <item>
        <title>Case-insensitive Sorting in Swift 3</title>
        <description>&lt;p&gt;Sorting with CoreData is pretty simple, but I ran into difficulty while trying to get string sorting to be case-insensitive.  Examples I found worked, but they gave deprecation warnings regarding using selectors.  This is the solution that worked for me:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-swift&quot; data-lang=&quot;swift&quot;&gt;&lt;span class=&quot;n&quot;&gt;sortDescriptors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;NSSortDescriptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                   &lt;span class=&quot;nv&quot;&gt;ascending&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                   &lt;span class=&quot;nv&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;#selector(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;NSString.localizedCaseInsensitiveCompare&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Of course this leaves out a lot of detail, but the importance of the example is in the proper (Swift 3) selector use.&lt;/p&gt;
</description>
        <pubDate>Sun, 11 Sep 2016 22:34:50 +0000</pubDate>
        <link>https://michaelteter.com/archived-posts/2016/09/11/swift-caseinsensitive-sorting-in-swift-3.html</link>
        <guid isPermaLink="true">https://michaelteter.com/archived-posts/2016/09/11/swift-caseinsensitive-sorting-in-swift-3.html</guid>
        
        <category>swift swift3 selector selectors</category>
        
        
      </item>
    
  </channel>
</rss>
