<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Rafał Sroka</title>
    <description>The latest articles on Forem by Rafał Sroka (@r3econ).</description>
    <link>https://forem.com/r3econ</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F249709%2F8e059332-d37e-4453-8c77-2d88d29ed491.jpg</url>
      <title>Forem: Rafał Sroka</title>
      <link>https://forem.com/r3econ</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/r3econ"/>
    <language>en</language>
    <item>
      <title>Extracting audio using youtube-dl</title>
      <dc:creator>Rafał Sroka</dc:creator>
      <pubDate>Sun, 10 Jul 2022 19:27:11 +0000</pubDate>
      <link>https://forem.com/r3econ/extracting-audio-using-youtube-dl-kne</link>
      <guid>https://forem.com/r3econ/extracting-audio-using-youtube-dl-kne</guid>
      <description>&lt;p&gt;Audio could be extracted from a YouTube video using &lt;code&gt;youtube-dl&lt;/code&gt; tool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;youtube-dl -x --audio-format mp3 https://www.youtube.com/watch?v=AtPS-pJwBL4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>music</category>
      <category>audio</category>
    </item>
    <item>
      <title>Loading locally created rule configuration to Karabiner</title>
      <dc:creator>Rafał Sroka</dc:creator>
      <pubDate>Sat, 09 Apr 2022 17:42:25 +0000</pubDate>
      <link>https://forem.com/r3econ/loading-locally-created-rule-configuration-to-karabiner-3c57</link>
      <guid>https://forem.com/r3econ/loading-locally-created-rule-configuration-to-karabiner-3c57</guid>
      <description>&lt;p&gt;I use a vintage left-handed vertical mouse. It has extra buttons that I have always mapped to &lt;code&gt;Copy&lt;/code&gt; and &lt;code&gt;Paste&lt;/code&gt; shortcuts to limit moving my hand back to the keyboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_MzQmekr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/44pvj74ezr8wrf0mjqdz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_MzQmekr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/44pvj74ezr8wrf0mjqdz.jpg" alt="Alt Text" width="880" height="1196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There were always problems with the mouse driver for macOS. At some point, the driver from Evoluent stopped working whatsoever and I had to look for an alternative. I'd been already using &lt;a href="https://karabiner-elements.pqrs.org/"&gt;Karabiner&lt;/a&gt; to configure custom keyboard mappings so I decided to give it a go and add mappings for the mouse.&lt;/p&gt;

&lt;p&gt;In order to create such mappings I had to configure a custom configuration rule and add it to &lt;em&gt;Complex Modifications&lt;/em&gt; in the Karabiner preferences.&lt;/p&gt;

&lt;p&gt;The following config maps button 4 and button 6 of the mouse to key combos &lt;code&gt;CMD + C&lt;/code&gt; and &lt;code&gt;CMD + V&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mouse button 4 to copy, button 6 to paste"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Maps mouse button 4 to CMD+C (copy), button 6 to CMD+V (paste).&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"manipulators"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"basic"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pointing_button"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"button4"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"repeat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"key_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"modifiers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"left_gui"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"basic"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"pointing_button"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"button6"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"repeat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"key_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"modifiers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"left_gui"&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Karabiner does not have an easy way of adding custom rules via the UI. There is an UI to import from the Internet or generate rules configuration via online tools.&lt;/p&gt;

&lt;p&gt;There is a way to make Karabiner use the locally created rule though. Here's how to do it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy the json file with the rule to &lt;code&gt;~/.config/karabiner/assets/complex_modifications&lt;/code&gt;. Name of the file does not matter. Do it by drag and dropping in Finder or use shell:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp &lt;/span&gt;public/json/rule_configuration.json ~/.config/karabiner/assets/complex_modifications
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Import rules from Karabiner-Elements Preferences. &lt;em&gt;Karabiner-Elements Preferences &amp;gt; Complex Modifications &amp;gt; Rules &amp;gt; Add rule&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I used Karabiner-Elements version 13.5.0.&lt;br&gt;
The mouse I use is Evoluent Vertical Mouse 4 (left-handed version).&lt;/p&gt;

</description>
      <category>karabiner</category>
      <category>custom</category>
      <category>configuration</category>
      <category>json</category>
    </item>
    <item>
      <title>Purge a soft-deleted Azure Key Vault</title>
      <dc:creator>Rafał Sroka</dc:creator>
      <pubDate>Sat, 09 Apr 2022 17:35:26 +0000</pubDate>
      <link>https://forem.com/r3econ/purge-a-soft-deleted-azure-key-vault-25gh</link>
      <guid>https://forem.com/r3econ/purge-a-soft-deleted-azure-key-vault-25gh</guid>
      <description>&lt;p&gt;If you came here you probably already know that delete a Key Vault in Azure is not as easy as it sounds. Sure, it's gone from the Azure portal. However, when you try to create one using the same name you'll find out that it was not fully deleted.&lt;/p&gt;

&lt;p&gt;The following recipe shows how to get rid of the Key Vault, for good. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install Azure CLI according to the &lt;a href="https://docs.microsoft.com/en-us/cli/azure/install-azure-cli"&gt;following steps&lt;/a&gt;. The example below uses &lt;code&gt;homebrew&lt;/code&gt; (macOS).&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; brew &lt;span class="nb"&gt;install &lt;/span&gt;azure-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Login and find the soft-deleted key vault you want to purge. If you happen to have multiple subscriptions, use the &lt;code&gt;--subscription&lt;/code&gt; param to indicate which one should be searched.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az login
az keyvault list-deleted
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Purge it&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az keyvault purge &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;keyvault-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>azure</category>
      <category>devops</category>
      <category>keyvault</category>
    </item>
    <item>
      <title>How to disable security in a PDF that prevents copy &amp; paste</title>
      <dc:creator>Rafał Sroka</dc:creator>
      <pubDate>Sat, 09 Apr 2022 17:25:33 +0000</pubDate>
      <link>https://forem.com/r3econ/how-to-disable-security-in-a-pdf-that-prevents-copy-paste-4gpg</link>
      <guid>https://forem.com/r3econ/how-to-disable-security-in-a-pdf-that-prevents-copy-paste-4gpg</guid>
      <description>&lt;p&gt;&lt;strong&gt;QPDF&lt;/strong&gt; is a hefty library that can inspect and manipulate the structure of PDF files. It can encrypt and expose the internals of a PDF file, and do many other operations useful to end users and PDF developers.&lt;/p&gt;

&lt;p&gt;Some PDF creators enable the read-only mode for their documents. In reality, this way of protection has little sense. It relies on PDF reader apps implementation letting them decide what to do when user tries to copy the text. Many of them show error alerts with a message about disabled copying. &lt;/p&gt;

&lt;p&gt;Of course, the text is visible, so nothing prevents us from reading it. The alerts become especially annoying if you own the PDF. You purchased it but since the protection mechanism is still there, you're not allowed to &lt;code&gt;CTRL + C&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The following recipe shows how to solve the problem.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download QPDF from the &lt;a href="https://sourceforge.net/projects/qpdf/"&gt;official website&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install it according to the instructions for your OS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;qpdf &lt;span class="nt"&gt;--decrypt&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;.pdf out.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>qpdf</category>
      <category>pdf</category>
    </item>
    <item>
      <title>How to switch AKS clusters</title>
      <dc:creator>Rafał Sroka</dc:creator>
      <pubDate>Sat, 09 Apr 2022 17:13:16 +0000</pubDate>
      <link>https://forem.com/r3econ/how-to-switch-aks-clusters-2ga6</link>
      <guid>https://forem.com/r3econ/how-to-switch-aks-clusters-2ga6</guid>
      <description>&lt;p&gt;The following recipe shows how to quickly change the Kubernetes context using Azure CLI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1.&lt;/strong&gt; Login to Azure with the Azure CLI&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2.&lt;/strong&gt; Get the list of AKS clusters&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az aks list &lt;span class="nt"&gt;-o&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3.&lt;/strong&gt; Switch cluster (context)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl config use-context &amp;lt;cluster-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>azure</category>
      <category>kubernetes</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
