<?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: Guionardo Furlan</title>
    <description>The latest articles on Forem by Guionardo Furlan (@guionardo).</description>
    <link>https://forem.com/guionardo</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%2F37248%2F6ed4b320-f9ac-401f-aec4-af926ffe30c0.png</url>
      <title>Forem: Guionardo Furlan</title>
      <link>https://forem.com/guionardo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/guionardo"/>
    <language>en</language>
    <item>
      <title>Python Virtual Environment Setup</title>
      <dc:creator>Guionardo Furlan</dc:creator>
      <pubDate>Mon, 12 Dec 2022 13:48:04 +0000</pubDate>
      <link>https://forem.com/guionardo/python-virtual-environment-setup-4o44</link>
      <guid>https://forem.com/guionardo/python-virtual-environment-setup-4o44</guid>
      <description>&lt;h1&gt;
  
  
  Python Virtual Environment Setup
&lt;/h1&gt;

&lt;p&gt;Post created at 2022-12-12 10:30&lt;/p&gt;

&lt;p&gt;Setting your virtual environment with another python version.&lt;/p&gt;

&lt;p&gt;While I'm writing this post, I'm using Ubuntu 22.04 LTS Jammy Jellyfish, wich has python 3.10.&lt;/p&gt;

&lt;p&gt;But, I need to work on a project that runs on python 3.8. To assure that the development environment will be the same to the production environment, I have to setup this. I don't want to use docker in this case.&lt;/p&gt;

&lt;p&gt;To start, we need to install required packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;dirmngr ca-certificates software-properties-common apt-transport-https &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will use the launchpad PPA's to get things done easely.&lt;/p&gt;

&lt;p&gt;Next, we need to install the GPG keys the repositories.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--list-keys&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
gpg: directory '/root/.gnupg' created
gpg: keybox '/root/.gnupg/pubring.kbx' created
gpg: /root/.gnupg/trustdb.gpg: trustdb created
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Now, wee need to import the GPG key.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--no-default-keyring&lt;/span&gt; &lt;span class="nt"&gt;--keyring&lt;/span&gt; /usr/share/keyrings/deadsnakes.gpg &lt;span class="nt"&gt;--keyserver&lt;/span&gt; keyserver.ubuntu.com &lt;span class="nt"&gt;--recv-keys&lt;/span&gt; F23C5A6CF475977595C89F51BA6932366A755776
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


Output
&lt;pre&gt;
gpg: key BA6932366A755776: public key "Launchpad PPA for deadsnakes" imported
gpg: Total number processed: 1
gpg: imported: 1
&lt;/pre&gt;

&lt;p&gt;If no errors, you can continue importing PPA. Use the command below to your installed version:&lt;/p&gt;

&lt;h2&gt;
  
  
  Ubuntu 22.04 LTS Jammy Jellyfish
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'deb [signed-by=/usr/share/keyrings/deadsnakes.gpg] https://ppa.launchpadcontent.net/deadsnakes/ppa/ubuntu jammy main'&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /etc/apt/sources.list.d/python.list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Ubuntu 20.04 LTS Focal Fossa
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'deb [signed-by=/usr/share/keyrings/deadsnakes.gpg] https://ppa.launchpadcontent.net/deadsnakes/ppa/ubuntu focal main'&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /etc/apt/sources.list.d/python.list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Complete the python3.8 installation:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;python3.8 python3.8-venv python3.8-python3.8-distutils python3.8-dev python3.8-dbg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Update pip
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3.8 &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;/p&gt;

&lt;pre&gt;
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: pip in /usr/lib/python3/dist-packages (22.0.2)
Collecting pip
 pip-22.3.1-py3-none-any.whl (2.1 MB)
 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 2.5 MB/s eta 0:00:00
Installing collected packages: pip
Successfully installed pip-22.3.1
&lt;/pre&gt;

&lt;h2&gt;
  
  
  Access your project folder on terminal:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/dev/my_project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create your virtual environment
&lt;/h2&gt;

&lt;p&gt;I like to use &lt;code&gt;.venv&lt;/code&gt; as virtual environment folder name, but you can use &lt;code&gt;venv&lt;/code&gt; or whatever you want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3.8 &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Checking the folder/files created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;✦ ❯ tree &lt;span class="nt"&gt;-L&lt;/span&gt; 2 .venv
.venv
├── bin
│ ├── activate
│ ├── activate.csh
│ ├── activate.fish
│ ├── Activate.ps1
│ ├── pip
│ ├── pip3
│ ├── pip3.8
│ ├── python -&amp;gt; python3.8
│ ├── python3 -&amp;gt; python3.8
│ └── python3.8 -&amp;gt; /usr/bin/python3.8
├── include
├── lib
│ └── python3.8
├── lib64 -&amp;gt; lib
└── pyvenv.cfg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Activating the virtual environment
&lt;/h2&gt;

&lt;p&gt;Visual Studio Code and another editors can automatically detect the virtual environment and activate it. In the terminal you should do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now, you can use the python that you need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ python --version
Python 3.8.16
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Post-setup
&lt;/h2&gt;

&lt;p&gt;After this, I usually install autopep8 and flake8 for linting/formatting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;autopep8 flake8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thanks for reading! Leave a comment and click the heart icon!&lt;/p&gt;

&lt;h2&gt;
  
  
  Links:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.linuxcapable.com/install-python-3-8-on-ubuntu-linux" rel="noopener noreferrer"&gt;How to Install Python 3.8 on Ubuntu 22.04/20.04&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>codepen</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Creating animated gifs from your terminal</title>
      <dc:creator>Guionardo Furlan</dc:creator>
      <pubDate>Fri, 19 Aug 2022 14:35:00 +0000</pubDate>
      <link>https://forem.com/guionardo/creating-animated-gifs-from-your-terminal-3oo5</link>
      <guid>https://forem.com/guionardo/creating-animated-gifs-from-your-terminal-3oo5</guid>
      <description>&lt;h1&gt;
  
  
  Creating animated gifs from your terminal
&lt;/h1&gt;

&lt;p&gt;Post created at 2022-08-19 08:36&lt;/p&gt;

&lt;p&gt;I need to generate some videos to demonstrate console applications running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fguionardo%2Fdev-to-blog%2Fraw%2Fmain%2Fposts%2Fcreating-animated-gifs-from-your-terminal%2Fdancing-duck-acegifcom-72.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fguionardo%2Fdev-to-blog%2Fraw%2Fmain%2Fposts%2Fcreating-animated-gifs-from-your-terminal%2Fdancing-duck-acegifcom-72.gif" alt="gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://acegif.com/wp-content/uploads/2022/4hv9xm/dancing-duck-acegifcom-72.gif" rel="noopener noreferrer"&gt;source&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Screen casting or capture is boring, and generates large files. &lt;/p&gt;

&lt;p&gt;Then, I found two command line tools that do the job.&lt;/p&gt;

&lt;p&gt;First, we need to capture the console interation, and this is done using the Terminal Session Recorder &lt;a href="https://asciinema.org/" rel="noopener noreferrer"&gt;asciinema&lt;/a&gt;. Installation instructions can be found &lt;a href="https://asciinema.org/docs/installation" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm using Ubuntu, so the installation was easy-peasy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;asciinema
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; senha para guionardo: 
A ler as listas de pacotes... Pronto
A construir árvore de dependências 
A ler a informação de estado... Pronto
Serão instalados os seguintes NOVOS pacotes:
 asciinema
0 pacotes actualizados, 1 pacotes novos instalados, 0 a remover e 0 não actualizados.
É necessário obter 35,0 kB de arquivos.
Após esta operação, serão utilizados 125 kB adicionais de espaço em disco.
Obter:1 http://br.archive.ubuntu.com/ubuntu focal/universe amd64 asciinema all 2.0.2-1 &lt;span class="o"&gt;[&lt;/span&gt;35,0 kB]
Obtidos 35,0 kB em 7s &lt;span class="o"&gt;(&lt;/span&gt;4.877 B/s&lt;span class="o"&gt;)&lt;/span&gt; 
A seleccionar pacote anteriormente não seleccionado asciinema.
&lt;span class="o"&gt;(&lt;/span&gt;A ler a base de dados ... 435184 ficheiros e directórios actualmente instalados.&lt;span class="o"&gt;)&lt;/span&gt;
A preparar para desempacotar .../asciinema_2.0.2-1_all.deb ...
A descompactar asciinema &lt;span class="o"&gt;(&lt;/span&gt;2.0.2-1&lt;span class="o"&gt;)&lt;/span&gt; ...
A instalar asciinema &lt;span class="o"&gt;(&lt;/span&gt;2.0.2-1&lt;span class="o"&gt;)&lt;/span&gt; ...
A processar &lt;span class="s1"&gt;'triggers'&lt;/span&gt; para man-db &lt;span class="o"&gt;(&lt;/span&gt;2.9.1-1&lt;span class="o"&gt;)&lt;/span&gt; ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For our first test, we can command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ asciinema rec first.cast
asciinema: recording asciicast to first.cast
asciinema: press &amp;lt;ctrl-d&amp;gt; or &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s2"&gt;"exit"&lt;/span&gt; when you&lt;span class="s1"&gt;'re done
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, you can run your commands normally and all your key strokes and console outputs will be recorded into the &lt;em&gt;first.cast&lt;/em&gt; file.&lt;/p&gt;

&lt;p&gt;To finish the capture press &lt;em&gt;CTRL+D&lt;/em&gt; or type &lt;em&gt;exit&lt;/em&gt;. Check the &lt;a href="https://asciinema.org/docs/usage" rel="noopener noreferrer"&gt;official usage documentation&lt;/a&gt; for more options.&lt;/p&gt;

&lt;p&gt;Now, we need to generate the animated gif file. The tool to this job is the might &lt;a href="https://github.com/asciinema/agg" rel="noopener noreferrer"&gt;agg - asciinema gif generator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's a &lt;a href="https://www.rust-lang.org/" rel="noopener noreferrer"&gt;rust&lt;/a&gt; application, and you can clone the repository and build it, or you can download a binary file compatible to your environment surfing to the &lt;a href="https://github.com/asciinema/agg/releases/latest" rel="noopener noreferrer"&gt;latest release link&lt;/a&gt;. Download the correct version to your system, put the executable in some directory you can reach and execute.&lt;/p&gt;

&lt;p&gt;If you have rust installed, you can simply run this to install agg:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--git&lt;/span&gt; https://github.com/asciinema/agg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check if the installation is OK.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ agg &lt;span class="nt"&gt;--version&lt;/span&gt;
agg 1.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your shell has some fancy unicode characters (like mine), you can reference a TTF font to render the gif.&lt;br&gt;
I like "JetBrains Mono", and you can download it from &lt;a href="https://www.jetbrains.com/lp/mono/" rel="noopener noreferrer"&gt;here&lt;/a&gt;, or if you like another dev font, you can use.&lt;/p&gt;

&lt;p&gt;In my case, I saved the TTF files into a folder (./fonts) to use in next step.&lt;/p&gt;

&lt;p&gt;Generate a gif from the &lt;em&gt;first.cast&lt;/em&gt; file created .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ ./agg &lt;span class="nt"&gt;--font-dir&lt;/span&gt; ./fonts &lt;span class="nt"&gt;--font-family&lt;/span&gt; &lt;span class="s2"&gt;"agave Nerd Font"&lt;/span&gt; first.cast first.gif
31 / 31 &lt;span class="o"&gt;[=================================================================]&lt;/span&gt; 100.00 % 47.71/s 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now, we have our &lt;em&gt;first.gif&lt;/em&gt; file in current folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fguionardo%2Fdev-to-blog%2Fraw%2Fmain%2Fposts%2Fcreating-animated-gifs-from-your-terminal%2Ffirst.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fguionardo%2Fdev-to-blog%2Fraw%2Fmain%2Fposts%2Fcreating-animated-gifs-from-your-terminal%2Ffirst.gif" alt="first"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>terminal</category>
      <category>gif</category>
      <category>linux</category>
    </item>
    <item>
      <title>Using local mail as notification tool</title>
      <dc:creator>Guionardo Furlan</dc:creator>
      <pubDate>Wed, 04 May 2022 18:50:55 +0000</pubDate>
      <link>https://forem.com/guionardo/using-local-mail-as-notification-tool-47k2</link>
      <guid>https://forem.com/guionardo/using-local-mail-as-notification-tool-47k2</guid>
      <description>&lt;h1&gt;
  
  
  Using local mail as notification tool
&lt;/h1&gt;

&lt;p&gt;Post created at 2022-05-04 14:25&lt;/p&gt;

&lt;p&gt;I used to run commands and develop into linux terminal, and have some scheduled tasks running in the background.&lt;/p&gt;

&lt;p&gt;I need to be notified on terminal about some finished processes in a generic form, without depending GUI notifications.&lt;/p&gt;

&lt;p&gt;By default, every cron job thats writes to console is sent to user local email. So, local email will be my notification messages repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;I used this setup in Ubuntu, but it must works in any distro.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Adding current user to &lt;strong&gt;mail&lt;/strong&gt; group
&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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;adduser &lt;span class="nv"&gt;$USER&lt;/span&gt; mail
Adding user &lt;span class="s1"&gt;'guionardo'&lt;/span&gt; to group &lt;span class="s1"&gt;'mail'&lt;/span&gt; ...
Adding user guionardo to group mail
Done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install mailtools, postfix, and mutt
&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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;mailtools postfix mutt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Send test mail
&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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"This is a test"&lt;/span&gt; | mail &lt;span class="s2"&gt;"--subject=Test email"&lt;/span&gt; &lt;span class="nv"&gt;$USER&lt;/span&gt;@localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Test new mail
&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="nv"&gt;$ &lt;/span&gt;mail
&lt;span class="s2"&gt;"/var/mail/guionardo"&lt;/span&gt;: 1 message 1 new
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;N 1 Guionardo Furlan qua mai 4 17:41 14/464 Test email
? q
Held 1 message &lt;span class="k"&gt;in&lt;/span&gt; /var/mail/guionardo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, we have an e-mail into our inbox. Lets read with better tool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;mutt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;q:Quit d:Del u:Undel s:Save m:Mail r:Reply g:Group ?:Help
 1 O F mai 04 To guionardo@lo &lt;span class="o"&gt;(&lt;/span&gt; 2&lt;span class="o"&gt;)&lt;/span&gt; Test email



&lt;span class="nt"&gt;---Mutt&lt;/span&gt;: /var/mail/guionardo &lt;span class="o"&gt;[&lt;/span&gt;Msgs:1 Old:1 0,6K]---&lt;span class="o"&gt;(&lt;/span&gt;threads/date&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nt"&gt;----&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;all&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;i:Exit -:PrevPg &amp;lt;Space&amp;gt;:NextPg v:View Attachm. d:Del r:Reply j:Next ?:He
Date: Wed, 4 May 2022 17:41:20 +0000 &lt;span class="o"&gt;(&lt;/span&gt;UTC&lt;span class="o"&gt;)&lt;/span&gt;
From: Guionardo Furlan &amp;lt;guionardo@furlan-server&amp;gt;
To: guionardo@localhost
Subject: Test email
X-Mailer: mail &lt;span class="o"&gt;(&lt;/span&gt;GNU Mailutils 3.7&lt;span class="o"&gt;)&lt;/span&gt;

This is a &lt;span class="nb"&gt;test&lt;/span&gt;


&lt;span class="nt"&gt;-O&lt;/span&gt; F- 1/1: Guionardo Furlan Test email &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;all&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Setup for notifications&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add this content to your ~/.profile or equivalent file (.bashrc, .zshrc, etc):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;MAIL_CHECK_TIME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
mail_prompt&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="nb"&gt;local pwd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'~'&lt;/span&gt;
 &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;MAIL_SECONDS_DIFF&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$MAILCHECK&lt;/span&gt;

 &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;MAIL_ELAPSED_SECONDS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;SECONDS &lt;span class="o"&gt;-&lt;/span&gt; MAIL_CHECK_TIME&lt;span class="k"&gt;))&lt;/span&gt;

 &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PWD&lt;/span&gt;&lt;span class="p"&gt;/#&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="p"&gt;//~/&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

 &lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;"033]0;%s@%s:%s033&lt;/span&gt;&lt;span class="se"&gt;\%&lt;/span&gt;&lt;span class="s2"&gt;s"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;USER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOSTNAME&lt;/span&gt;&lt;span class="p"&gt;%%.*&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;pwd&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

 &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MAIL_CHECK_TIME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MAIL_ELAPSED_SECONDS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MAIL_SECONDS_DIFF&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
 &lt;/span&gt;&lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;MAILX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;mailx 2&amp;gt;/dev/null &amp;amp;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
 &lt;span class="nv"&gt;UNREADEN_REGEX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"s([0-9]{1,4})sn"&lt;/span&gt;
 &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$MAILX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;~ &lt;span class="nv"&gt;$UNREADEN_REGEX&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;UNREADEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BASH_REMATCH&lt;/span&gt;&lt;span class="p"&gt;[1]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nv"&gt;UNREADEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
 &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;UNREADEN&lt;span class="k"&gt;))&lt;/span&gt;
 &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;MESSAGE_TEXT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"message"&lt;/span&gt;
 &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$COUNT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
 if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$COUNT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; &lt;span class="s2"&gt;"1"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
 &lt;/span&gt;&lt;span class="nv"&gt;MESSAGE_TEXT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"messages"&lt;/span&gt;
 &lt;span class="k"&gt;fi
 &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$COUNT&lt;/span&gt;&lt;span class="s2"&gt; unreaden &lt;/span&gt;&lt;span class="nv"&gt;$MESSAGE_TEXT&lt;/span&gt;&lt;span class="s2"&gt;. Run mutt"&lt;/span&gt;
 &lt;span class="k"&gt;fi
 &lt;/span&gt;&lt;span class="nv"&gt;MAIL_CHECK_TIME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$SECONDS&lt;/span&gt;
 &lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;which mailx&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
 &lt;/span&gt;&lt;span class="nv"&gt;PROMPT_COMMAND&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"mail_prompt"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Close and reopen your terminal to load this configuration&lt;/li&gt;
&lt;li&gt;Now, when you access the terminal, messages not readden will show a prompt:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;1 unreaden message. Run mutt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your custom scripts, you can send email to your local user and get notified.&lt;/p&gt;

</description>
      <category>mail</category>
      <category>linux</category>
      <category>terminal</category>
      <category>notification</category>
    </item>
    <item>
      <title>HTTP Hello World server for testing purposes (part 1)</title>
      <dc:creator>Guionardo Furlan</dc:creator>
      <pubDate>Sat, 12 Mar 2022 13:08:21 +0000</pubDate>
      <link>https://forem.com/guionardo/http-hello-world-server-for-testing-purposes-part-1-387h</link>
      <guid>https://forem.com/guionardo/http-hello-world-server-for-testing-purposes-part-1-387h</guid>
      <description>&lt;h1&gt;
  
  
  HTTP Hello World server for testing purposes
&lt;/h1&gt;

&lt;p&gt;Post created at 2022-03-12 09:53&lt;/p&gt;

&lt;p&gt;I needed a http server, small, minimalistic, just for proxy testing.&lt;/p&gt;

&lt;p&gt;There are many options to do this, but I wanted to create my own solution.&lt;/p&gt;

&lt;p&gt;A basic golang project, with only native components, generating a docker image with 10MB. Just K.I.S.S. !&lt;/p&gt;

&lt;p&gt;The repository for this project is in &lt;a href="https://github.com/guionardo/http_helloworld"&gt;github.com/guionardo/http_helloworld&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All what we need to do to use this tool is run a docker command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 guionardo/http_helloworld:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>go</category>
      <category>http</category>
      <category>server</category>
      <category>testing</category>
    </item>
    <item>
      <title>Fast folder iteration in python</title>
      <dc:creator>Guionardo Furlan</dc:creator>
      <pubDate>Fri, 21 Jan 2022 00:26:12 +0000</pubDate>
      <link>https://forem.com/guionardo/fast-folder-iteration-in-python-3g1f</link>
      <guid>https://forem.com/guionardo/fast-folder-iteration-in-python-3g1f</guid>
      <description>&lt;h1&gt;
  
  
  Fast folder iteration in python
&lt;/h1&gt;

&lt;p&gt;Post created at 2022-01-19 07:53&lt;/p&gt;

&lt;p&gt;I have a problem to deal here.&lt;/p&gt;

&lt;p&gt;I need to iterate over a big tree of folders and files and run process over each file.&lt;/p&gt;

&lt;p&gt;In python, we have some options to deal to folders and files.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;glob&lt;/li&gt;
&lt;li&gt;iglob&lt;/li&gt;
&lt;li&gt;os.walk&lt;/li&gt;
&lt;li&gt;os.scandir&lt;/li&gt;
&lt;li&gt;pathlib.Path&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Running this benchmark, we can read some implementation details:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://docs.python.org/3/library/glob.html#glob.glob"&gt;glob&lt;/a&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;glob&lt;/span&gt;

&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'some_folder/another_folder/**/*'&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;recursive&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;some_folder/another_folder/f1/file1
some_folder/another_folder/f1/file1
some_folder/another_folder/f1/file2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Easy to use, less code to write&lt;/li&gt;
&lt;li&gt;Easy to apply filters using masks (fnmatch based)&lt;/li&gt;
&lt;li&gt;Returns data as a list&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Time to scan is the worst (more than 11x the quickest method)&lt;/li&gt;
&lt;li&gt;Data will be available only after all files/folders been scanned&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://docs.python.org/3/library/glob.html#glob.iglob"&gt;iglob&lt;/a&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;glob&lt;/span&gt;

&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'some_folder/another_folder/**/*'&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iglob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;recursive&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;some_folder/another_folder/f1/file1
some_folder/another_folder/f1/file1
some_folder/another_folder/f1/file2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Easy to use, like glob&lt;/li&gt;
&lt;li&gt;Same filtering&lt;/li&gt;
&lt;li&gt;Returns data as iterator, so you can have your data without need to wait all iteration ending.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Time to scan is a little better than glob (10x the quickest method)&lt;/li&gt;
&lt;li&gt;Time to first file could be mutch better&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://docs.python.org/3/library/os.html#os.walk"&gt;os.walk&lt;/a&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;

&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'some_folder/another_folder/**/*'&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;walk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Good performance. Second quickest method (less than 2x slower than the quickest)&lt;/li&gt;
&lt;li&gt;Time for the first file almost imediattely (better result of all)&lt;/li&gt;
&lt;li&gt;Explicit code in loops gives more visibility and control if you need validations or another nasty processes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;More code needed, with nested loops. &lt;/li&gt;
&lt;li&gt;If you need to nest os.walk in another os.walk loop, some strange things can ocurr. But probably your code needs some refactoring.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://docs.python.org/3/library/os.html#os.walk"&gt;os.scandir&lt;/a&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Generator&lt;/span&gt;

&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'some_folder/another_folder/**/*'&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_files&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Generator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scandir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_file&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
 &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;
 &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;subitem&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;get_files&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;subitem&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Best performance of all&lt;/li&gt;
&lt;li&gt;Context based, assure resources are released after processing&lt;/li&gt;
&lt;li&gt;Less verbose than os.walk&lt;/li&gt;
&lt;li&gt;Easy to implement your custom business rules&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A little more complex. No big deal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://docs.python.org/3/library/pathlib.html"&gt;pathlib.Path.rglob&lt;/a&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pathlib&lt;/span&gt;

&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'some_folder/another_folder'&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;rglob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_file&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
 &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Easy to implement your custom business rules&lt;/li&gt;
&lt;li&gt;Returns a iterator&lt;/li&gt;
&lt;li&gt;You can have your files soon and don't need to wait for all scan (7x more time than os.scandir)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Average time to scan (almost 8 times greater than os.scandir)&lt;/li&gt;
&lt;li&gt;Memory consumption is 4 times more than the other methods&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Some data from tests
&lt;/h2&gt;

&lt;h2&gt;
  
  
  System Information
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;System&lt;/th&gt;
&lt;th&gt;Release&lt;/th&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;th&gt;Machine&lt;/th&gt;
&lt;th&gt;Processor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Linux&lt;/td&gt;
&lt;td&gt;5.11.0-46-generic&lt;/td&gt;
&lt;td&gt;#51~20.04.1-Ubuntu SMP Fri Jan 7 06:51:40 UTC 2022&lt;/td&gt;
&lt;td&gt;x86_64&lt;/td&gt;
&lt;td&gt;x86_64&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  CPU Info
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Physical cores&lt;/th&gt;
&lt;th&gt;Total cores&lt;/th&gt;
&lt;th&gt;Max frequency&lt;/th&gt;
&lt;th&gt;Min frequency&lt;/th&gt;
&lt;th&gt;Current frequency&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;3400&lt;/td&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;1.892&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  CPU Usage Per Core
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;0&lt;/th&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;2&lt;/th&gt;
&lt;th&gt;3&lt;/th&gt;
&lt;th&gt;4&lt;/th&gt;
&lt;th&gt;5&lt;/th&gt;
&lt;th&gt;6&lt;/th&gt;
&lt;th&gt;7&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;15.6&lt;/td&gt;
&lt;td&gt;16.5&lt;/td&gt;
&lt;td&gt;10.4&lt;/td&gt;
&lt;td&gt;14.1&lt;/td&gt;
&lt;td&gt;15.2&lt;/td&gt;
&lt;td&gt;14.4&lt;/td&gt;
&lt;td&gt;15.2&lt;/td&gt;
&lt;td&gt;12.4&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Memory Information
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;th&gt;Available&lt;/th&gt;
&lt;th&gt;Used&lt;/th&gt;
&lt;th&gt;Percentage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;15.51GB&lt;/td&gt;
&lt;td&gt;4.77GB&lt;/td&gt;
&lt;td&gt;9.56GB&lt;/td&gt;
&lt;td&gt;69.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  SWAP
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;th&gt;Free&lt;/th&gt;
&lt;th&gt;Used&lt;/th&gt;
&lt;th&gt;Percentage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;15.26GB&lt;/td&gt;
&lt;td&gt;3.28GB&lt;/td&gt;
&lt;td&gt;11.98GB&lt;/td&gt;
&lt;td&gt;78.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Creating sample files
 + Creating folder ./test_files
 + Creating files LEVELS=6 FOLDER_COUNT=6 FILE_COUNT_BY_FOLDER=20
 + Created 933120 files in 0:02:08.928680

* Running iterators: GlobFolderIterator IGlobFolderIterator OSWalkFolderIterator ScanDirIterator PathLibFolderIterator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  MEMORY USAGE
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Iterator&lt;/th&gt;
&lt;th&gt;RSS&lt;/th&gt;
&lt;th&gt;VMS&lt;/th&gt;
&lt;th&gt;DATA&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;IGlobFolderIterator&lt;/td&gt;
&lt;td&gt;111280128&lt;/td&gt;
&lt;td&gt;96468992&lt;/td&gt;
&lt;td&gt;96468992&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OSWalkFolderIterator&lt;/td&gt;
&lt;td&gt;111280128&lt;/td&gt;
&lt;td&gt;96468992&lt;/td&gt;
&lt;td&gt;96468992&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ScanDirIterator&lt;/td&gt;
&lt;td&gt;111280128&lt;/td&gt;
&lt;td&gt;96468992&lt;/td&gt;
&lt;td&gt;96468992&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GlobFolderIterator&lt;/td&gt;
&lt;td&gt;117309440&lt;/td&gt;
&lt;td&gt;102498304&lt;/td&gt;
&lt;td&gt;120254464&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PathLibFolderIterator&lt;/td&gt;
&lt;td&gt;469721088&lt;/td&gt;
&lt;td&gt;455081984&lt;/td&gt;
&lt;td&gt;455081984&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  ELAPSED TIME
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Iterator&lt;/th&gt;
&lt;th&gt;Elapsed time&lt;/th&gt;
&lt;th&gt;X&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ScanDirIterator&lt;/td&gt;
&lt;td&gt;0:00:01.317526&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OSWalkFolderIterator&lt;/td&gt;
&lt;td&gt;0:00:02.496639&lt;/td&gt;
&lt;td&gt;1.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PathLibFolderIterator&lt;/td&gt;
&lt;td&gt;0:00:10.464794&lt;/td&gt;
&lt;td&gt;7.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IGlobFolderIterator&lt;/td&gt;
&lt;td&gt;0:00:14.358165&lt;/td&gt;
&lt;td&gt;10.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GlobFolderIterator&lt;/td&gt;
&lt;td&gt;0:00:15.308936&lt;/td&gt;
&lt;td&gt;11.6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  TIME FOR FIRST FILE
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Iterator&lt;/th&gt;
&lt;th&gt;Elapsed time&lt;/th&gt;
&lt;th&gt;X&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ScanDirIterator&lt;/td&gt;
&lt;td&gt;0:00:00.000098&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OSWalkFolderIterator&lt;/td&gt;
&lt;td&gt;0:00:00.000247&lt;/td&gt;
&lt;td&gt;2.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PathLibFolderIterator&lt;/td&gt;
&lt;td&gt;0:00:00.000690&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IGlobFolderIterator&lt;/td&gt;
&lt;td&gt;0:00:00.001135&lt;/td&gt;
&lt;td&gt;11.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GlobFolderIterator&lt;/td&gt;
&lt;td&gt;0:00:07.831005&lt;/td&gt;
&lt;td&gt;79908.2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You can check the source code for this &lt;a href="https://github.com/guionardo/python-folder-iteration"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Image from this wikipedia &lt;a href="https://en.wikipedia.org/wiki/International_Committee_of_the_Red_Cross_archives"&gt;article&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
    </item>
    <item>
      <title>Automatizando a publicação de artigos no dev.to com github actions</title>
      <dc:creator>Guionardo Furlan</dc:creator>
      <pubDate>Wed, 03 Nov 2021 13:11:04 +0000</pubDate>
      <link>https://forem.com/guionardo/automatizando-a-publicacao-de-artigos-no-devto-com-github-actions-24ac</link>
      <guid>https://forem.com/guionardo/automatizando-a-publicacao-de-artigos-no-devto-com-github-actions-24ac</guid>
      <description>&lt;h1&gt;
  
  
  Automatizando publicações de artigos no dev.to com github actions
&lt;/h1&gt;

&lt;p&gt;Recentemente decidi começar a escrever sobre problemas que encontro diariamente no desenvolvimento e as soluções encontradas. &lt;/p&gt;

&lt;p&gt;Entre as opções de plataformas de publicação, uma que eu gosto bastante é a &lt;a href="https://dev.to/about"&gt;dev.to&lt;/a&gt; por alguns motivos: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;É uma comunidade de desenvolvedores&lt;/li&gt;
&lt;li&gt;É construída com base em software open source (&lt;a href="https://forem.com"&gt;Forem&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Não custa nada para quem escreve e nem para quem lê.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eu já tinha alguns assuntos para começar a tratar aqui, mas resolvi organizar as postagens em uma plataforma centralizada, onde eu poderia de qualquer lugar, escrever, pensar, unir material e manter os dados em um local que eu sempre tenha acesso. Como nem tudo são flores no mundo open-source, não posso confiar que meus posts no dev.to ficarão lá para sempre.&lt;/p&gt;

&lt;p&gt;Então, parti da ideia de criar um repositório no github para guardar meus artigos.&lt;/p&gt;

&lt;p&gt;E já que os artigos ficariam no github, porque não automatizar a tarefa de publicação usando o github actions?&lt;/p&gt;

&lt;p&gt;Ok, primeira coisa a ser verificada. O dev.to tem alguma API? &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tem! &lt;a href="https://developers.forem.com/api"&gt;DEV API&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos precisar de três operações dessa API.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://developers.forem.com/api#operation/createArticle"&gt;Criar artigo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.forem.com/api#operation/updateArticle"&gt;Editar artigo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.forem.com/api#operation/getArticleById"&gt;Obter dados de um artigo pelo seu ID&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Então, precisamos ter um usuário registrado na plataforma. Como você é um desenvolvedor safo, não vou me preocupar com estas &lt;a href="https://dev.to/enter?state=new-user"&gt;instruções&lt;/a&gt;, ok?&lt;/p&gt;

&lt;p&gt;Após logar no dev.to, acesse as &lt;a href="https://dev.to/settings/account"&gt;configurações da conta&lt;/a&gt; e crie uma API key. Guarde essa chave para usarmos em seguida.&lt;/p&gt;

&lt;p&gt;No próximo post, vamos configurar o repositório que usaremos para guardar os artigos e que automatizará a formatação e publicação.&lt;/p&gt;

</description>
      <category>github</category>
      <category>actions</category>
    </item>
    <item>
      <title>Guardando seus segredos com segurança</title>
      <dc:creator>Guionardo Furlan</dc:creator>
      <pubDate>Tue, 02 Nov 2021 13:01:49 +0000</pubDate>
      <link>https://forem.com/guionardo/guardando-seus-segredos-com-seguranca-3km</link>
      <guid>https://forem.com/guionardo/guardando-seus-segredos-com-seguranca-3km</guid>
      <description>&lt;h1&gt;
  
  
  Segredos
&lt;/h1&gt;

&lt;p&gt;O gerenciamento de senhas pode ser complicado quando temos vários serviços (e-mail, redes sociais, github, API´s, certificados digitais, orkut :-) , etc).&lt;/p&gt;

&lt;p&gt;A regra é usar senhas complexas, &lt;em&gt;pass phrases&lt;/em&gt;, cuidando pra não incluir dados pessoais, como aniversário, apelidos, nomes de conhecidos, etc que possam ser "adivinhados" por engenharia social.&lt;/p&gt;

&lt;p&gt;E quando você cria sua senha super exclusiva e segura, encontra sistemas que expiram as senhas periodicamente e impedem que a reutilize.&lt;/p&gt;

&lt;p&gt;Então, em nosso socorro, existem ferramentas para criar, gerenciar senhas, como o &lt;a href="https://keepassxc.org/"&gt;KeepassXC&lt;/a&gt;. Além de armazenar usuários e senhas, a ferramenta permite documentar e adicionar arquivos, como exemplos de requests/responses de API, arquivos de chaves, certificados digitais, etc. O KeepassXC armazena todas essas informações em um arquivo local criptografado (database .kdbx).&lt;/p&gt;

&lt;p&gt;Existem outros, mas esse é um que eu gosto de usar e me atende muito bem. KeepassXC é open-source, roda em Windows, Linux, e Mac. É facilmente instalado. Siga o link acima e sucesso!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gTEc8drH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y3aym8qsc2dgny6d1ejg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gTEc8drH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y3aym8qsc2dgny6d1ejg.png" alt="Alt Text" width="128" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, já resolvi o meu problema com muitas informações de autenticação e esbarrei em outro: Quando eu uso em mais de uma máquina, preciso me preocupar com a distribuição e sincronização do meu database por todas as minhas máquinas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dropbox.com"&gt;Dropbox&lt;/a&gt;, &lt;a href="https://drive.google.com"&gt;Google Drive&lt;/a&gt;, &lt;a href="https://onedrive.live.com"&gt;OneDrive&lt;/a&gt; poderiam ser uma opção, mas eu gostaria de algo mais hipster. Brincadeira. Se estamos falando em segurança de informação, dá pra confiar nos grandes players? Talvez.&lt;/p&gt;

&lt;p&gt;Aí, encontrei o &lt;a href="https://keybase.io"&gt;Keybase&lt;/a&gt;, que, entre outras coisas, permite um sistema de &lt;a href="https://keybase.io/docs/kbfs"&gt;arquivos&lt;/a&gt; em nuvem e &lt;a href="https://keybase.io/docs/crypto/kbfs"&gt;criptografado&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---3l7x1AQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hkvk3yrg6o68vru1qjxe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---3l7x1AQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hkvk3yrg6o68vru1qjxe.png" alt="Alt Text" width="48" height="48"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então, vamos por mãos à obra.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalação
&lt;/h2&gt;

&lt;p&gt;Acesse o site do &lt;a href="https://keybase.io/download"&gt;Keybase&lt;/a&gt;, escolha seu ambiente (macOS, Windows ou Linux), faça o download e instale normalmente. Siga as instruções de instalação e depois crie seu usuário com uma senha segura ;-)&lt;/p&gt;

&lt;p&gt;Depois do keybase devidamente instalado, acesse as opções de arquivo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7Q4DwSrH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5uvyne0b0yz3r29wfvxl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Q4DwSrH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5uvyne0b0yz3r29wfvxl.png" alt="Alt Text" width="759" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E clique em "Yes, enable" para instalar o Dokan Library, que permitirá montar o sistema de arquivos em uma unidade do sistema (K: geralmente, no Windows, e /keybase no Linux e no macOS)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WxOpK9iP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xcbs6tn0avqqg1zwbw4n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WxOpK9iP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xcbs6tn0avqqg1zwbw4n.png" alt="Alt Text" width="48" height="48"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TODO: Continuar
&lt;/h2&gt;

</description>
      <category>secrets</category>
      <category>keepass</category>
      <category>keybase</category>
    </item>
  </channel>
</rss>
