Category Archives: Linux

Automatic download of album covers

Automatic download of album covers (with a Simple Bash Script)

Managing a digital music library can be both fun and a little obsessive. If you’re like me, you don’t just want your tracks properly tagged, you need them to look good too. Having the album cover right there makes browsing way more satisfying (and helps music servers like Navidrome or Jellyfin look polished).

That’s why I put together a small Bash script that automatically fetches album art using Last.fm. No need to manually copy-paste images anymore, just run the script in your album folder, and it does the heavy lifting for you.

How It Works

The idea is simple:

  1. Guess the album artist and title from the current folder (with some prompts if you want).
  2. Construct the right Last.fm album page URL.
  3. Parse the page to find the cover image.
  4. Download it to cover.jpg.

That’s it. Nothing magical, but it saves a lot of clicking.

Here’s the script itself:

#!/bin/bash

set -e

_error()
{
    echo "$(basename "$0" .sh): $1" >&2
    exit "$2"
}

_info()
{
        echo "[INFO] $*"
}

urlencode()
{
        local length="${#1}"

        for ((i=0; i<length; i++)); do
                local c="${1:i:1}"

                case $c in
                        [a-zA-Z0-9.~_-])
                                printf '%s' "$c"
                                ;;
                        ' ')
                                printf "%%20"
                                ;;
                        *)
                                printf '%%%02X' "'$c"
                                ;;
                esac
        done
        echo
}

##
# Init
#
umask 0002
output="cover.jpg"
batch=

##
# Checks
#
[[ ! -r $output ]] || _error "$output exists" 2
[[ $1 = '--batch' ]] && batch=1

##
# Main
#
defaultArtist="$(cd .. && basename "$(pwd)")"
defaultAlbum="$(basename "$(pwd)")"
if [[ $batch -ne 1 ]]; then
        read -p "artist [$defaultArtist]: " artist
        read -p "album [$defaultAlbum]: " album
fi
[[ -z $artist ]] && artist="$defaultArtist"
[[ -z $album ]] && album="$defaultAlbum"

{
        url="https://www.last.fm/music/$(urlencode "$artist")/$(urlencode "$album")"
        _info "search cover url in $url"
        cover_url="$(wget "$url" -O - | pup 'div.album-overview-cover-art img attr{src}')"
        [[ -n $cover_url ]] || _error 'cannot find cover_url' 5
        _info "download cover url $cover_url"
        curl -s "$cover_url" >"$output"
        [[ -r $output ]]
} || _error "cannot find cover" 99

echo
echo "Done"
exit 0

Usage

Run this script inside your album’s folder. For example:

~/music/navidrome/Afterhours/Ballate per piccole iene$ download-album-cover.sh
artist [Afterhours]:
album [Ballate per piccole iene]:
[INFO] search cover url in https://www.last.fm/music/Afterhours/Ballate%20per%20piccole%20iene
--2025-09-11 09:42:43--  https://www.last.fm/music/Afterhours/Ballate%20per%20piccole%20iene
Resolving www.last.fm (www.last.fm)... 151.101.241.188, 2a04:4e42:39::444
Connecting to www.last.fm (www.last.fm)|151.101.241.188|:443... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: /music/Afterhours/Ballate+Per+Piccole+Iene [following]
--2025-09-11 09:42:48--  https://www.last.fm/music/Afterhours/Ballate+Per+Piccole+Iene
Reusing existing connection to www.last.fm:443.
HTTP request sent, awaiting response... 200 OK
Length: 632693 (618K) [text/html]
Saving to: ‘STDOUT’

-                                      100%[=========================================================================>] 617.86K  4.00MB/s    in 0.2s

2025-09-11 09:42:50 (4.00 MB/s) - written to stdout [632693/632693]

[INFO] download cover url https://lastfm.freetls.fastly.net/i/u/500x500/d0993bb25c9ea5085beb29486dcb5408.jpg

Done

When executed, it will suggest the folder names as defaults for artist and album. You can simply hit enter if they’re correct, or type something else if not.

  • By default, it downloads the cover as cover.jpg.
  • If you already have a cover.jpg file, it won’t overwrite it.
  • There’s also a --batch mode to skip interaction, which can be handy if you want automation.

Dependencies

You’ll need:

  • wget (to fetch the Last.fm HTML)
  • pup (for HTML parsing)
  • curl (to download the image)

On most Linux distros, these are easy to install with your package manager.

Why This Is Handy

For someone running a headless server or managing a huge MP3/FLAC collection, this is a lifesaver. Media players and tools like Navidrome, Jellyfin, or even plain old file explorers look so much better with consistent artwork. And because it’s just a shell script, you can tweak it however you like, change defaults, switch sources, or even integrate into a bigger tagging pipeline.

How to Install Tasmota on Shelly 1 from Linux

This guide will show you how to flash Tasmota firmware onto a Shelly 1 device using Linux. You will use the PlatformIO toolchain to communicate with the device, erase the existing firmware, and install the Tasmota firmware via serial communication. After flashing, you’ll configure the device to connect to your Wi-Fi and MQTT broker.

Prerequisites

  1. Linux PC
  2. Shelly 1 device
  3. USB to Serial adapter (e.g., FTDI adapter)
  4. Jumper wires to connect the Shelly 1 to the USB-to-serial adapter
  5. Tasmota binary downloaded to your local machine

Make sure that PlatformIO and Python 3 are installed on your system.

Step 1: Install PlatformIO

If you don’t already have PlatformIO installed, you can install it via Python’s package manager pip:

pip install platformio

This installs the platformio command-line interface (CLI), which will be used to flash the firmware onto the Shelly 1.

Step 2: Connect Shelly 1 to Your Linux PC

  1. Disconnect Shelly 1 from mains power to avoid electric shock.
  2. Connect the TX, RX, GND, and VCC pins of the Shelly 1 to the corresponding pins of your USB-to-serial adapter (TX->RX, RX->TX, GND->GND, VCC->3.3V). GPIO0 has to be temporary connected to GND to enter programming mode.
  3. Plug the USB-to-serial adapter into your Linux PC.
  4. You can now disconnect GPIO0 from GND or leave it as is.

Step 3: Test Communication with the Device

Before proceeding with the flashing, test whether your Linux PC can communicate with the Shelly 1 via serial.

Run the following command to check communication (replace /dev/ttyUSB0 with your actual serial device if needed):

python3 ~/.platformio/packages/tool-esptoolpy/esptool.py -p /dev/ttyUSB0 flash_id

If the communication is successful, you should see information about the connected ESP8266 chip inside the Shelly 1.

Step 4: Erase the Flash Memory

You have to reconnect the device to the pc as seen in Step 2.

Next, you need to erase the existing firmware on the device to ensure a clean installation of Tasmota. To erase the flash memory, run the following command:

python3 ~/.platformio/packages/tool-esptoolpy/esptool.py -p /dev/ttyUSB0 erase_flash

This process clears the current firmware from the Shelly 1.

Step 5: Flash Tasmota Firmware

You have to reconnect the device to the pc as seen in Step 2.

Once the flash memory is erased, you can now flash the Tasmota firmware onto the device. Replace the path ~/Downloads/tasmota.bin with the actual path to your downloaded Tasmota binary file:

python3 ~/.platformio/packages/tool-esptoolpy/esptool.py -p /dev/ttyUSB0 write_flash -fm dout 0x0 ~/Downloads/tasmota.bin

This writes the Tasmota firmware onto the Shelly 1.

Step 6: Configure the Device via Serial

After flashing, you can configure the Shelly 1 via serial connection using picocom. If it’s not installed on your system, you can install it with:

sudo apt install picocom

To open a serial connection, run:

picocom --echo --omap crcrlf --baud 115200 /dev/ttyUSB0

Once connected, you will see the device’s output. You can now paste the following configuration string to set up Wi-Fi and MQTT parameters:

Backlog ssid1 YourSSID; password1 veryStrongWiFiPassword; MqttHost 192.168.1.200; Template {"NAME":"Shelly 1","GPIO":[1,1,0,1,224,192,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":46};

Parameters in the Configuration String:

  • ssid1: Replace YourSSID with the name of your Wi-Fi network.
  • password1: Replace veryStrongWiFiPassword with your Wi-Fi password.
  • MqttHost: Set this to the IP address of your MQTT broker (e.g., 192.168.1.200).
  • Template: This defines the GPIO pin mapping for the Shelly 1.

Step 7: Verify the Device Connection

Once the Shelly 1 reboots, it should connect to your Wi-Fi and MQTT broker based on the configuration provided. You can now control it via the MQTT interface or the Tasmota web interface.


Congratulations! You have successfully flashed and configured Tasmota on your Shelly 1 device from Linux.

Statically compile redis 3.0.2 on CentOS 5 (RHEL 5)

How to statically compile redis 3.0.2 on CentOS 5 (RHEL 5)

wget http://download.redis.io/releases/redis-3.0.2.tar.gz
wget http://prdownloads.sourceforge.net/tcl/tcl8.5.18-src.tar.gz

Install tcl8.5

tar xfz tcl8.5.18-src.tar.gz
cd tcl8.5.18/unix
./configure
make
make test
make install

Compile redis

Statically linked binaries

make CFLAGS="-static" EXEEXT="-static" LDFLAGS="-I/usr/local/include/"

Dynamically linked binaries

make LDFLAGS="-I/usr/local/include/"

How to manually install redis

cd src/
cp redis-{server,cli} /usr/local/bin/
chown root: /usr/local/bin/redis-{server,cli}
chmod 755 /usr/local/bin/redis-{server,cli}
mkdir /{var,etc}/redis /var/redis/6379
chmod 775 /{var,etc}/redis
cp redis.conf /etc/redis/6379.conf
sed -i 's/daemonize no/daemonize yes/' /etc/redis/6379.conf
sed -i 's,pidfile /var/run/redis.pid,pidfile /var/run/redis_6379.pid,' /etc/redis/6379.conf
sed -i 's/^# bind 127.0.0.1/bind 127.0.0.1/' /etc/redis/6379.conf
sed -i 's,logfile "",logfile "/var/log/redis_6379.log",' /etc/redis/6379.conf
sed -i 's,dir ./,dir /var/redis/6379,' /etc/redis/6379.conf

Useful aptitude commands

A simple list of installed packages

max@wonko:~$ aptitude search '~i' -F '%p'

Search for installed packages from the testing repo

max@wonko:~$ aptitude versions '~i ~Atesting' --group-by=none

Finding why a package is installed

I found fonts-font-awesome in my headless server, but there’s a reason

max@wonko:~$ aptitude why fonts-font-awesome
i   owncloud Depends fonts-font-awesome

Select packages that were removed but not purged

max@wonko:~$ aptitude search '~c'

Search in the package description

max@wonko:~$ aptitude search '~d"web browser"'

Upgradable packages

max@wonko:~$ aptitude search '~U'

How to compile rsync for Android in Ubuntu

My situation

My machine

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04 LTS
Release:    14.04
Codename:   trusty

The latest rsync version to compile (for me it was rsync-3.1.0.tar.gz)

$ curl -s http://rsync.samba.org/ftp/rsync/ \
    | sed -r 's/^.*href="([^"]*)".*$/\1/' | grep 'rsync-[0-9].*\.tar\.gz$'

Procedure

  1. save the tarball name in a variable
    $ RSYNCTGZ="rsync-3.1.0.tar.gz"
    
  2. install needed software
    $ sudo aptitude install gcc-arm-linux-gnueabi
    
  3. download sources
    $ wget http://rsync.samba.org/ftp/rsync/$RSYNCTGZ
    $ tar xzf $RSYNCTGZ
    $ cd rsync-[0-9]*
    
  4. compile
    $ ./configure --host=arm-linux-gnueabi CFLAGS=-static
    $ make
    
  5. install on the device
    $ adb push rsync /data/local/tmp && adb shell chmod 775 /data/local/tmp/rsync
    
  6. test execution
    $ adb shell /data/local/tmp/rsync
    

References