<?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: Hyena</title>
    <description>The latest articles on Forem by Hyena (@hyenast2).</description>
    <link>https://forem.com/hyenast2</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%2F5002%2F53aac333-b5cb-4de0-9bb4-d18e74f0ea85.jpg</url>
      <title>Forem: Hyena</title>
      <link>https://forem.com/hyenast2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hyenast2"/>
    <language>en</language>
    <item>
      <title>HTML canvas, web components and pianos.</title>
      <dc:creator>Hyena</dc:creator>
      <pubDate>Fri, 09 Dec 2022 21:53:23 +0000</pubDate>
      <link>https://forem.com/hyenast2/html-canvas-web-components-and-pianos-mo7</link>
      <guid>https://forem.com/hyenast2/html-canvas-web-components-and-pianos-mo7</guid>
      <description>&lt;p&gt;If you've ever thought about starting to code a music web application, chances are you've needed a piano keyboard in your HTML.&lt;/p&gt;

&lt;p&gt;Notice how little code is needed to add a keyboard to an HTML page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;piano-keyboard&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"800"&lt;/span&gt; &lt;span class="na"&gt;octaves=&lt;/span&gt;&lt;span class="s"&gt;"5"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/piano-keyboard&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/gh/rafapaezbas/piano-keyboard/piano-keyboard.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;&amp;lt;piano-keyboard&amp;gt;&lt;/code&gt; ? That tag doesn't exist! No problem, web components to the rescue!&lt;/p&gt;

&lt;p&gt;If you don't know what a web component is, let me explain quickly: a web component is a fully customized html element, but it's just as easy to use as any standard web element. You can see a good tutorial following this &lt;a href="https://www.webcomponents.org/introduction"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Or maybe you are interested in seeing the &lt;a href="https://github.com/rafapaezbas/piano-keyboard"&gt;full code of the component.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A calendar, a knob or a writing keyboard are good candidates to create a web component due to their reusability. Create the component and reuse or share the code. Also don't be afraid that the component's logic will interfere with your application's logic, this logic is fully encapsulated! A web component can only communicate with its parent by emitting events.&lt;/p&gt;

&lt;p&gt;A simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// hello-world-component.js&lt;/span&gt;

&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello-world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;HelloWorld&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;HTMLElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attachShadow&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;open&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;connectedCallback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;CustomEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello-world-event, { detail: { message: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;hello&lt;/span&gt; &lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; }, bubbles: true, composed: true }))
  }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To include the component in your HTML page just add the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;hello-world&amp;gt;&amp;lt;/hello-world&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"hello-world-component.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello-world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello-world-event&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's that easy to create your own web component!&lt;/p&gt;

&lt;p&gt;Of course, the combination of web components and HTML canvas offers endless possibilities. It's easy to imagine a collection of components that makes building and maintaining web applications truly modular.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>piano</category>
      <category>html</category>
      <category>webcomponents</category>
    </item>
    <item>
      <title>Migrating web server from Ubuntu to FreeBSD</title>
      <dc:creator>Hyena</dc:creator>
      <pubDate>Sun, 16 May 2021 13:05:49 +0000</pubDate>
      <link>https://forem.com/hyenast2/migrating-web-server-from-ubuntu-to-freebsd-1b87</link>
      <guid>https://forem.com/hyenast2/migrating-web-server-from-ubuntu-to-freebsd-1b87</guid>
      <description>&lt;p&gt;Recently, I bought a second-hand HPE DL360e Gen 8 with the idea of trying to stop the EC2 instance where I host my personal website/online radio station.&lt;br&gt;
First decision I had to take was the OS I would use. I tried to install Ubuntu Server unsuccessfully, so FreeBSD was my next option on the list.&lt;/p&gt;

&lt;p&gt;According to the official &lt;a href="https://www.freebsd.org/"&gt;FreeBSD page&lt;/a&gt; "FreeBSD is an operating system used to power modern servers, desktops, and embedded platforms." and "FreeBSD is an operating system for a variety of platforms which focuses on features, speed, and stability. It is derived from BSD, the version of UNIX® developed at the University of California, Berkeley. It is developed and maintained by a large community".&lt;/p&gt;

&lt;p&gt;FreeBSD offers great documentation, all of it you can find in &lt;a href="https://docs.freebsd.org/en/books/faq/"&gt;https://docs.freebsd.org/en/books/faq/&lt;/a&gt;. It has an amazing community hanging on &lt;a href="https://forums.freebsd.org/"&gt;https://forums.freebsd.org/&lt;/a&gt; and IRC.&lt;/p&gt;

&lt;p&gt;One of the main differences with a Linux OS is that Docker is not supported on FreeBSD but a great alternative is available, jails and the easy-to-use jails manager &lt;a href="https://www.freebsd.org/cgi/man.cgi?query=ezjail"&gt;ezjail&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Those two approaches have some similarities on the surface, but are pretty much different once you start working with them.&lt;/p&gt;

&lt;p&gt;We can consider both of them as containerization technologies. That means isolated processes from the host server. But FreeBSD's jails takes the concept further, since each jail has its own directory sub-tree (vs. Docker mounted volumes) and its own set of users and groups. That means is easy to create a jail, enable ssh, and a secure environment is created within the host.&lt;br&gt;
On the other hand, Docker as standard is a fact, but keep in mind that these tools serve different purposes.  &lt;/p&gt;

&lt;p&gt;Ezjail makes the management of the jails a pretty easy job, see the "hello world" of it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Create a clone of the loopback interface
echo 'cloned_interfaces="lo1"' &amp;gt;&amp;gt; /etc/rc.conf
service netif cloneup
ezjail-admin create hello-world 'lo1|127.0.1.1'
# add dns nameserver for the jail
cp /etc/resolv.conf /usr/jails/hello-world/etc/
ezjail-admin start -f hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to forward all the traffic from the jail through the external interface, we can use the FreeBSD &lt;a href="https://www.freebsd.org/cgi/man.cgi?pf.conf(5)"&gt;packet filter&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ext_if="xn0"
jail_net="127.0.1.1"
nat pass on $ext_if from $jail_net to any -&amp;gt; $ext_if
pass out
pass in
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can also redirect some of the host ports to the jails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rdr pass on $ext_if inet proto { tcp, udp } from any to $ext_if_private_ip port 23 -&amp;gt; $jail_net port 22
rdr pass on $ext_if inet proto { tcp, udp } from any to $ext_if_private_ip port 81 -&amp;gt; $jail_net port 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition we can use Nginx to configure a different domain for each jail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;events {
    worker_connections  4096;  ## Default: 1024
}

http {

    log_format upstreamlog '[$time_local] $remote_addr - $remote_user - $server_name $host to: $upstream_addr: $request $status upstream_response_time $upstream_response_time msec $msec request_time $request_time';

    access_log /var/log/nginx/access.log upstreamlog;

    include "servers/*.conf";

}

&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;upstream example {
    server 127.0.1.1:443;
}

server {
    listen 80;
    server_name www.example.com example.com;
    return 301 https://$host$request_uri;
}

server{

    listen 443 ssl;
    server_name www.example.com example.com;
    ssl_certificate /home/ssl/example/fullchain.pem;
    ssl_certificate_key /home/ssl/example/privkey.pem;

    location / {
        proxy_pass https://example;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In conclusion FreeBSD can offer a very nice alternative to Docker, running on a robust OS, with many good parts like the &lt;a href="https://docs.freebsd.org/en/books/handbook/zfs/"&gt;ZFS&lt;/a&gt; file system, its cleanliness and predictability, and the great documentation available.&lt;/p&gt;

</description>
      <category>freebsd</category>
      <category>jails</category>
    </item>
    <item>
      <title>Mini-mp3-player</title>
      <dc:creator>Hyena</dc:creator>
      <pubDate>Sun, 10 Jan 2021 12:18:53 +0000</pubDate>
      <link>https://forem.com/hyenast2/mini-mp3-player-54p</link>
      <guid>https://forem.com/hyenast2/mini-mp3-player-54p</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/rafapaezbas/mini-mp3-player"&gt;https://github.com/rafapaezbas/mini-mp3-player&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is mini-mp3-player?
&lt;/h2&gt;

&lt;p&gt;Mini-mp3-player is a minimal, distracionless terminal mp3 player.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you use it?
&lt;/h2&gt;

&lt;p&gt;First thing you have to do is compiling the source code. Mini-mp3-player is coded in C and uses &lt;a href="https://www.libsdl.org/download-2.0.php"&gt;SDL2&lt;/a&gt; and &lt;a href="https://invisible-mirror.net/archives/ncurses/"&gt;Ncurses&lt;/a&gt; libreries.&lt;/p&gt;

&lt;p&gt;The code and compilation has only been tested in a Ubuntu system, the followed step are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apt-get install libsdl2-dev libsdl2-mixer-2.0-0 libncurses5-dev libncursesw5-dev &amp;amp;&amp;amp; make install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Once the code has been compiled run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mini-mp3-player -c {path-to-music-collection}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create or refresh a collection file used by mini-mp3-player.&lt;br&gt;
If you already have a collection, only run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mini-mp3-player
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Skip to next song pressing -n- or quit pressing -q-&lt;/p&gt;

</description>
      <category>c</category>
      <category>mp3player</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Neal Stephenson's Cryptonomicon and Ordoemacs</title>
      <dc:creator>Hyena</dc:creator>
      <pubDate>Sat, 19 Dec 2020 16:36:37 +0000</pubDate>
      <link>https://forem.com/hyenast2/neal-stephenson-s-cryptonomicon-and-ordoemacs-4g4c</link>
      <guid>https://forem.com/hyenast2/neal-stephenson-s-cryptonomicon-and-ordoemacs-4g4c</guid>
      <description>&lt;h1&gt;
  
  
  Ordoemacs.
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What is Ordoemacs?
&lt;/h2&gt;

&lt;p&gt;Ordoemacs is a fictional piece of software appearing in Neal Stephenson 1999 speculative fiction novel Cryptonomicon. In the book, Epiphyte is a corporation in the mission of creating a data haven. The members of Epiphyte use their own encryption software called Ordo (abbr. for "Novus ordo seclorum"), that was created by one of them. In addition, Randall "Randy" Lawrence Waterhouse uses a modified version of Emacs called Ordoemacs, decribed like this on the novel:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Returning to his seat, he fires up OrdoEmacs, which is a marvelously paranoid piece of software invented by John Cantrell. Emacs in its normal form is the hacker’s word processor, a text editor that offers little in the way of fancy formatting capabilities but does the basic job of editing plain text very well. Your normally cryptographically paranoid hacker would create files using Emacs and then encrypt them with Ordo later. But if you forget to encrypt them, or if your laptop gets stolen before you get a chance to, or your plane crashes and you die but your laptop is sieved out of the muck by baffled-but-dogged crash investigators and falls into the hands of federal authorities, your files can be read. For that matter it is possible even to find ghostly traces of old bits on a hard drive’s sectors even after the file has been overwritten with new data.&lt;br&gt;
OrdoEmacs, on the other hand, works exactly like regular Emacs, except that it encrypts everything before writing it out to disk. At no time is plaintext ever laid down on a disk by OrdoEmacs—the only place it exists in its plain, readable form is in the pixels on the screen, and in the volatile RAM of the computer, whence it vanishes the moment power is shut down. Not only that, but it’s coupled to a screensaver that uses the little built-in CCD camera in the laptop to check to see if you are actually there. It can’t recognize your face, but it can tell whether or not a vaguely human-shaped form is sitting in front of it, and if that vaguely human-shaped form goes away, even for a fraction of a second, it will drop into a screen-saver that will blank the display and freeze the machine until such time as you type in a password, or biometrically verify your identity through voice recognition.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Basically Ordoemacs is able to do two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encprypts every file before writing it to disk.&lt;/li&gt;
&lt;li&gt;Is able to check if someone is actually in front of the computer, if not, the program will drop into a screen-saver until the owner logs in again.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What a fantastic idea! The concept is so well explained and original that is it makes de reader imagination fly. The author already saw the potencial of a camera attached to a computer for user indetification. Now, this part of the plot is based on the year 1997, 23 years later face recognition would also be totally posible!&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating an Emacs minor mode for simuting Ordoemacs.
&lt;/h2&gt;

&lt;p&gt;The flexibility of Emacs, allows to create a minor-mode (an optional mode that alters the functionality of Emacs) binded to a file extension, in this case ".ordo".&lt;br&gt;
This minor mode will work for the first point mentioned before, with the help of &lt;a href="https://gnupg.org/"&gt;Gnu Privacy Guard&lt;/a&gt;, it will encrypt and decrypt files only storing the plain content in RAM. Also, it will use an usb storage for saving the encryption key.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Install gpg, openssl and emacs.&lt;/li&gt;
&lt;li&gt;Mount the usb storage device in the folder /media/usb-drive:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mount /dev/sda /media/usb-drive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Generate random key:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl rand -base64 16 &amp;gt;&amp;gt; /media/usb-drive/passphrase.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Include minor mode in Emacs config.el:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;define-minor-mode&lt;/span&gt; &lt;span class="nv"&gt;ordoemacs-mode&lt;/span&gt;
  &lt;span class="s"&gt;"Ordoemacs mode."&lt;/span&gt;
  &lt;span class="ss"&gt;:lighter&lt;/span&gt; &lt;span class="s"&gt;"ordoemacs"&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'after-save-hook&lt;/span&gt; &lt;span class="ss"&gt;'encrypt&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;encrypt&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="s"&gt;"Encrypts the buffer and replaces file content"&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;output-path&lt;/span&gt; &lt;span class="s"&gt;"/dev/shm/w_temp"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;write-region&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="nv"&gt;output-path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;shell-command&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;concat&lt;/span&gt; &lt;span class="s"&gt;"gpg --batch --passphrase-file /media/usb-drive/passphrase.txt -c "&lt;/span&gt; &lt;span class="nv"&gt;output-path&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;shell-command&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;concat&lt;/span&gt; &lt;span class="s"&gt;"rm "&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer-file-name&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;shell-command&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;concat&lt;/span&gt; &lt;span class="s"&gt;"mv /dev/shm/w_temp.gpg "&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer-file-name&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;shell-command&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;concat&lt;/span&gt; &lt;span class="s"&gt;"rm "&lt;/span&gt; &lt;span class="nv"&gt;output-path&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;decrypt&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="s"&gt;"Checks if file exists, if it does, decrypts it and inserts the content to the buffer."&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file-exists-p&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer-file-name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;output-path&lt;/span&gt; &lt;span class="s"&gt;"/dev/shm/temp"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;shell-command&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;concat&lt;/span&gt; &lt;span class="s"&gt;"gpg --batch --passphrase-file /media/usb-drive/passphrase.txt -o "&lt;/span&gt; &lt;span class="nv"&gt;output-path&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer-file-name&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;insert-file-contents&lt;/span&gt; &lt;span class="nv"&gt;output-path&lt;/span&gt;  &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;shell-command&lt;/span&gt; &lt;span class="s"&gt;"rm /dev/shm/temp"&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;enable-ordoemacs-mode&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="s"&gt;"Enables ordoemacs mode and decrypts file."&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;progn&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ordoemacs-mode&lt;/span&gt; &lt;span class="mi"&gt;+1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;disable-ordoemacs-mode&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="s"&gt;"Disables ordo emacs mode."&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;progn&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ordoemacs-mode&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;remove-hook&lt;/span&gt; &lt;span class="ss"&gt;'after-save-hook&lt;/span&gt; &lt;span class="ss"&gt;'encrypt&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="c1"&gt;;;; Every time a file is open, it enables or disables ordoemacs-mode&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'find-file-hook&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;string=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file-name-extension&lt;/span&gt; &lt;span class="nv"&gt;buffer-file-name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;"ordo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;enable-ordoemacs-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;disable-ordoemacs-mode&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  What is /dev/shm?
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;/dev/shm&lt;/code&gt; is a temporary that uses RAM normally functioning as a shared memory space for inter process communication.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;

&lt;p&gt;Create a file with extension ".ordo". After save, the &lt;code&gt;encrypt&lt;/code&gt;  function will execute, encrypting the file using &lt;code&gt;/dev/shm&lt;/code&gt; and storing the content in the buffer file location. In order to use it, the usb-storage must be mounted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some conclusions.
&lt;/h2&gt;

&lt;p&gt;I am very impressed with the power of the Emacs editor. Without serious Lisp experience, in some hours I have been able to put together a pretty decent implementation of Ordoemacs.&lt;br&gt;
On the other side, even though I see the power of Lisp, I cannot ignore how primitive the syntax is, making the language to difficult to use, at least from my perspective.&lt;br&gt;
Neal Stephenson is one of the greatest of our time. His books a full of breaking concepts and the writing is just fenomenal, do not miss any of his books!&lt;/p&gt;

&lt;p&gt;Github: &lt;a href="https://github.com/rafapaezbas/ordoemacs"&gt;https://github.com/rafapaezbas/ordoemacs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>fiction</category>
      <category>emacs</category>
      <category>crypto</category>
      <category>books</category>
    </item>
    <item>
      <title>Sidecar pattern and Ursc</title>
      <dc:creator>Hyena</dc:creator>
      <pubDate>Tue, 11 Aug 2020 17:39:41 +0000</pubDate>
      <link>https://forem.com/hyenast2/sidecar-pattern-and-ursc-3pmg</link>
      <guid>https://forem.com/hyenast2/sidecar-pattern-and-ursc-3pmg</guid>
      <description>&lt;h2&gt;
  
  
  Sidecar pattern
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/rafapaezbas/ursc"&gt;https://github.com/rafapaezbas/ursc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The sidecar pattern is a distrbuted single node application pattern where a side application is used to extend functionality of the main application. Ursc can keep track of registration and login of users for another application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ursc
&lt;/h2&gt;

&lt;p&gt;Ursc is a containerized sidecar application that help on keeping registration and login of user for any application.&lt;/p&gt;

&lt;p&gt;Ursc has a very simple API:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;/user/register&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -v -X POST -H "Content-Type: application/json"  -d '{"name":"name","password":"password"}'  localhost:8083/user/register
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Returns 201 if user is created, if there is already  a user with the same name, response is code 403.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;/user/login&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -v -X POST -H "Content-Type: application/json"  -d '{"name":"name","password":"password"}'  localhost:8080/user/login
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Returns 200 and a signed JWT token if credentials are correct, otherwise response will be code 403.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;/user/check&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -i -H "Authorization: Basic eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhYSIsImlhdCI6MTU5NzA3OTUwMCwiZXhwIjoxNTk3MDgzMTAwfQ.VCGsGjpAMEVUzQu2twamNUrbFeyjNECGjeq0nxlDlm1" -X GET localhost:8080/user/check
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Check validity of the token sent in the Authorization header and returns 200 code with the name of user if the token is valid, if not response is 422.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tutorial
&lt;/h2&gt;

&lt;p&gt;If you want to deploy Ursc you also need a MongoDB instance. Make sure your database is up and running then have a look on the configuration file config.conf:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jwt_sign_secret=0123456
encryption_salt=0123456
mongodb_url=mongodb://mongodb:27017
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Change the jwt signature and encryption salt to make your application saver. Then run init.sh, now you should have a Docker container running Ursc!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Link mongodb container with alias "mongodb", expose application on port 8083
./init.sh -l mongodb:mongodb -p 8080 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>sidecar</category>
      <category>ursc</category>
      <category>pattern</category>
    </item>
    <item>
      <title>Cmus-analytics</title>
      <dc:creator>Hyena</dc:creator>
      <pubDate>Thu, 30 Jul 2020 14:07:00 +0000</pubDate>
      <link>https://forem.com/hyenast2/cmus-analytics-no6</link>
      <guid>https://forem.com/hyenast2/cmus-analytics-no6</guid>
      <description>&lt;h2&gt;
  
  
  What is &lt;a href="https://rafapaezbas.github.io/cmus-analytics/docs/index.html" rel="noopener noreferrer"&gt;Cmus-analytics&lt;/a&gt;?
&lt;/h2&gt;

&lt;p&gt;A small web application for data visualization extracted from a Cmus log file. Click on the example link and then import it.You will see something like this:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fonic87qjq9xl3vgbeuil.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fonic87qjq9xl3vgbeuil.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How can I get a Cmus log file?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cmus.github.io/" rel="noopener noreferrer"&gt;Cmus&lt;/a&gt; is a very powerful music player with a lot possibilities. One of them is using a hook script for actions when the player status changes. With this script, you can create your own Cmus log file.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I set the script in Cmus?
&lt;/h2&gt;

&lt;p&gt;First, you will have to modify the script (the one in the tools folder) in order to make it work in your computer. Change the path of the log file.&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="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;$is_playing&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&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="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$is_logging&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;
&lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$entry&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;path_to_the_log_file&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Cmus use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:set status_display_program {path_to_the_script}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Can I use this code somehow?
&lt;/h2&gt;

&lt;p&gt;Yes, of course! Please be so kind to do it. This application has been developed as a learning project of the Elm programing language. It also uses this awesome Elm &lt;a href="https://github.com/terezka/line-charts/" rel="noopener noreferrer"&gt;linear charts library&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>cmus</category>
      <category>elm</category>
    </item>
    <item>
      <title>Tape-selecta Online Radio Station </title>
      <dc:creator>Hyena</dc:creator>
      <pubDate>Thu, 19 Mar 2020 10:04:06 +0000</pubDate>
      <link>https://forem.com/hyenast2/tape-selecta-online-radio-station-3hma</link>
      <guid>https://forem.com/hyenast2/tape-selecta-online-radio-station-3hma</guid>
      <description>

&lt;h2&gt;
  
  
  What is Tape-selecta?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/rafapaezbas/tape-selecta"&gt;Tape-selecta&lt;/a&gt; is a dockerized &lt;a href="https://icecast.org/"&gt;Icecast2&lt;/a&gt; server together with &lt;a href="https://icecast.org/ezstream/"&gt;Ezstream&lt;/a&gt; and &lt;a href="https://nodejs.org/en/"&gt;Node.js&lt;/a&gt; that makes the perfect way to set up your own &lt;strong&gt;online radio station&lt;/strong&gt; following just a few simple steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;The setup is very simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install &lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Copy your &lt;strong&gt;mp3&lt;/strong&gt; files into the &lt;em&gt;music&lt;/em&gt; directory.&lt;/li&gt;
&lt;li&gt;Run &lt;em&gt;start.sh&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Check &lt;strong&gt;localhost:8000/mountpoint&lt;/strong&gt;, your music should be streaming there!&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The selector.sh
&lt;/h2&gt;

&lt;p&gt;The selector.sh is the script that chooses what is the next file to be streamed. By default, the script just randomly picks the next file to be played. Have a look at the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#pick a random mp3 file under /home/music&lt;/span&gt;
&lt;span class="nv"&gt;song&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;find /home/music &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.mp3 | &lt;span class="nb"&gt;shuf&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 1&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c"&gt;#write mp3 tag information to status.json&lt;/span&gt;
mp3info &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s1"&gt;'{"title": "%t","artist": "%a" ,"category": "'&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;genre&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s1"&gt;'"}'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$song&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /home/info.json
&lt;span class="c"&gt;#echo the info&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$song&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;Before running your online radio station, it is important to make some security changes to the configuration of the &lt;a href="https://icecast.org/"&gt;Icecast2&lt;/a&gt; server. Change the content of the file &lt;strong&gt;icecast-config/icecast.xml&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;authentication&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Sources log in with username 'source' --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;source-password&amp;gt;&lt;/span&gt;password&lt;span class="nt"&gt;&amp;lt;/source-password&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Relays log in with username 'relay' --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;relay-password&amp;gt;&lt;/span&gt;password&lt;span class="nt"&gt;&amp;lt;/relay-password&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Admin logs in with the username given below --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;admin-user&amp;gt;&lt;/span&gt;admin&lt;span class="nt"&gt;&amp;lt;/admin-user&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;admin-password&amp;gt;&lt;/span&gt;password&lt;span class="nt"&gt;&amp;lt;/admin-password&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/authentication&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After this change the content of the &lt;strong&gt;ezstream-config/ezstream_mp3.xml&lt;/strong&gt; file to match the password choosen for the Icecast2 admin user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;sourcepassword&amp;gt;&lt;/span&gt;password&lt;span class="nt"&gt;&amp;lt;/sourcepassword&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are some other configuration options in both xml files please check the &lt;a href="https://www.icecast.org/docs/"&gt;Icecast documentation page&lt;/a&gt; and &lt;a href="https://icecast.org/ezstream/"&gt;Ezstream documentation page&lt;/a&gt; to know more on the subject.&lt;/p&gt;

&lt;h2&gt;
  
  
  Front end
&lt;/h2&gt;

&lt;p&gt;The code of the project includes an &lt;a href="https://expressjs.com/"&gt;Express&lt;/a&gt;/&lt;a href="https://nodejs.org/en/"&gt;Node.js&lt;/a&gt; server, ready to the static files included in the &lt;strong&gt;web/public&lt;/strong&gt; directory.&lt;br&gt;
Futhermore, it is possible to retrieve the information of the current track playing in the endpoint &lt;strong&gt;localhost/status&lt;/strong&gt;, the information can be useful in case we want to show information of the track provided by the mp3 tags of the file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;If you setup your own radio station, please let me know! It would be great to have a community of self hosted stations and get to know your ideas for it.&lt;/p&gt;

</description>
      <category>icecast</category>
      <category>radiostation</category>
      <category>streaming</category>
    </item>
  </channel>
</rss>
