Archive for the ‘Webtechnology’ Category

No Comments

Install separate Firefox (Beta) Snap on Ubuntu 22.04

Wednesday, August 3rd, 2022

To try out a beta version of Firefox snap, you have to enable the experimental – read developer options – of parallel instances install of snap.

sudo snap set system experimental.parallel-instances=true

Them you can install a beta version of Firefox next to the stable version

sudo snap install --beta firefox_beta

But that doesn’t work, you will probably get some error/warning message like this:

error: cannot perform the following tasks:
- Set automatic aliases for snap "firefox_beta" (cannot enable alias "geckodriver" for "firefox_beta", already enabled for "firefox")

As it seems you’ll need to add  --unaliased when installing firefox_beta

sudo snap install --beta --unaliased firefox_beta

See the snap forum thread

That does work.

How to install Firefox Beta snap parallel to Firefox

sudo snap install --beta --unaliased firefox_beta
firefox_beta (beta) 104.0b5-1 from Mozilla✓ installed

To my surprise it copied the profile directory, I had all the same extensions and bookmarks installed and available.

Different profile directories

Firefox stable profiles path:


Firefox Beta profiles path:


No Comments

Scanning the WiFi network with the Raspberry Pi Pico W

Friday, July 22nd, 2022

Let’s try the Wifi features of the new Raspberry Pi Pico W.

The Pico W has two Wifi interfaces:

  • network.STA_IF, the station interface
  • network.AP_IF, the access-point interface


The station (or standard) interface, can be used to connect the Pico W to another 2.4GHz WiFi access point. This seems to be the default.


The access-point interface can be used to turn your Pico W into a WiFi access-point that can connect up to 4 devices at the moment.

Use the Pico W to scan access points

Let’s try out the station interface, network.STA_IF.

Using micropython it’s really a breeze:

import network
import binascii
wlan = network.WLAN() #  network.WLAN(network.STA_IF)
networks = wlan.scan() # list with tupples with 6 fields ssid, bssid, channel, RSSI, security, hidden
networks.sort(key=lambda x:x[3],reverse=True) # sorted on RSSI (3)
for w in networks:

In most example code you need to specify the interface, but apparently it defaults to the standard station network.STA_INF interface.

The output is a list with tupples that according to the docs should contain six fields ssid, bssid, channel, RSSI, security, hidden.

The bssid is the same as the hardware unique MAC-address.

There are five values for security:

  1. open (0)
  2. WEP (1)
  3. WPA-PSK (2)
  4. WPA2-PSK(3)
  5. WPA/WPA2-PSK (4)

and two for hidden:

  1. visible (0)
  2. hidden (1)

The docs states that for hidden 0 = visible and  1 = hidden, but actually the output I get, some twenty networks(!?) gives no 0, but several undocumented values for hidden: 1,2,3,4,5,7.

Twenty WiFi-networks? Yes, I do work in a city. And that’s only the 2.4GHz band. 🙁

So what does those values mean, what is there more than visible or hidden?

Also the security results differ with outputs from 0 (=open), most 5, but some report 7.

What do those values for security mean?

Is it a bug or a (undocumented) feature?

No Comments

Blinking a led on the Raspberry Pi Pico W

Thursday, July 21st, 2022

One much requested feature has landed to the Raspberry Pi Pico, and that is connection, Wifi and in the future Bluetooth are added, and that new Raspberry Pi Pico W just landed in my postbox.

Blinking a led is the first thing most lads try out, a bit like printing “Hello World” in any new program language.

The official documentation gives this example

from machine import Pin
led = Pin(25, Pin.OUT)
led.value(1) // led on
led.value(0) // led off

I blinked my eye twice, but running this code the Pico W did not light its led.

How to blink a led on the Raspberry Pi Pico W

I did remember reading about a change in GPIO pins, because the Wifi-modules needed some for connection, but I was surprised it was not mentioned in the official Raspberry Pi Pico documentation.

Actually with the introduction of the Wifi variant there are changes made in the micropython framework, to let the same code blink a led on any Raspberry Pi Pico, they gave the needed pin a name; “LED”, and added two functions, on and off.

from machine import Pin
led = Pin("LED", Pin.OUT)
led.on()  // a method instead of setting the value // turn it off again.

Do remember you need to download a different firmware for the Pico and the Pico W.

No Comments

Adding virtual columns in MySQL/MariaDB

Wednesday, June 22nd, 2022

A small MariaDB database with a simple table with just a couple of columns (id, name, `description` ) drives a PHP website. The table lacks a `slug` column.

You could still get away with spaces in an URL although it’s against the specs.

`” Doe”` will work if you parse “John Doe” to a variable and do a search in your database.

select * from `people` where `name` like 'John Doe' limit 1

But you can’t copy the url, it will lose Doe.

Spitting out a better url with a slug/url PHP function should output something like `””`

But then there is a problem in the database:

select * from `people` where `name` like 'john-doe' limit 1

doesn’t return anything.

So we need to add a `slug` column to the database, and why not try out a VIRTUAL column. A virtual column doesn’t exist in memory of disk, but is generated on the fly.

Can that work?

To sluggify a string in MariaDB, is a bit problematic, probably you should write you own custom function but I took the easy road. The REPLACE function which can only REPLACE one character a time, it doesn’t have the more powerful TRANSLATE function, but you can nest the REPLACE function so that should do the job.

Adding a virtual slug column to a Maria/MySQL database

Not really clean and concise but let’s try:

ALTER TABLE `users` add `slug` VARCHAR(50) AS (LOWER(REPLACE(REPLACE(REPLACE(`name`," ","-"),"(",""),")",""))) VIRTUAL;

Filtering out spaces, and brackets.

Doesn’t work. Doesn’t even execute.

Got this error in  PHPMyAdmin:


Static analysis:

3 errors were found during analysis.

 	A new statement was found, but no delimiter between it and the previous one. (near "replace" at position 52)

 	Unrecognized alter operation. (near "," at position 68)
 	Unrecognized alter operation. (near "" at position 0)


Took me some time to find out was wrong.


It’s a bug in PHPMyAdmin!

Executing the same command in a MySQL console worked perfectly fine.

A search on the internet gave me this issue, guess my PHPMyAdmin is too old on my local server.

Anyhow for the moment I’m testing a virtual `slug` column instead of a real one. Should save some MB on expensive disk-space.


No Comments

Setting several properties of dataset of any DOM element, writing to the dataset property

Tuesday, June 21st, 2022

One of the greatest additions in writing JS of the last years for writing clean code are arrow functions, classes and several ways of Destructuring assingment.

Arrow functions let you skip, several verbose terms like the function keyword, return keyword and {} character, while maintaining readability. Easy, once you mastered the new syntax!.

What is Destructuring assingment?

Let’s assume you fetch a stock json:

let json= {name:"SHELL PLC",isin:"GB00BP6MXD84",price:"25.00","volume":"2500000",time:"2022-06-22:09-06"}

They old way of dealing with this was to write everything out to assign values to variables:

var name =;
var isin= json.isin
var price = json.price;
var volume=json.volume;
var time = json.time;

Destructuring assingment let you do this more succinct:

let {name,isin,price,volume,time}=json

That is nice code.

Destructuring arrays, or csv rows:

let {name,isin,price,volume,time}=row.split(",")

Sure there is more on parsing cvs rows than just splitting on “,” but this is an example and you get the drift. When you totally control the csv file, using “,” only as separator, it should do the job.

Writing to the datatset property?

I dearly miss something for setting the dataset property of an element concisely.

The dataset read-only property of the HTMLElement interface provides read/write access to custom data attributes (data-*) on elements.

Note: The dataset property itself can be read, but not directly written. Instead, all writes must be to the individual properties within the dataset, which in turn represent the data attributes.

So you can’t simply do something like this:


You have to write it all out, and that is  verbose:

let elStock = document.querySelector("#stock");

Well there is a workaround.

Imitate writing to the dataset property directly, Object.assign()

According to the specs you can’t directly write the dataset, but you can do this:



<body data-name="SHELL PLC" data-isin="GB00BP6MXD84" data-price="25.00" data-volume="2500000" data-time="2022-06-22:09-06">

A piece of cake. That is as easy as writing the directly.

To extract dataset into variables destructuring assignment does work.

let {name,isin,price}=document.body.dataset

I used `Object.assign` in an older project for writing several properties to the style attribute, but it works as well for the dataset property.

No Comments

How to check the Signing Certificate on an Android app / apk (II)

Friday, June 17th, 2022

This is an 2022 update of an older post.

If you own a Android Phone, and you want to use Signal instead of Whatsapp or Telegram for privacy matters, and, for the same privacy matters, you prefer to use open source Android AOSP instead of the commercial Android variant that is enriched spoiled with proprietary Google services,  or you don’t have a Google Account on your phone, or you don’t use Google Play but the free F-Droid software-store, there is a solution. You can download the Signal APK from their website.

To verify that the signing certificate on the APK matches the SHA256 fingerprint on the Signal website you can use the following one-liner.

As Matthew (kudos) pointed out, the certification file has a new name in recent Signal APK’s.

So the one-liner changed a bit:

f="Signal-Android-website-prod-universal-release-5.40.4.apk" ; unzip -p "$f" $(unzip -l "$f" | grep '.RSA' | awk '{print $4}') | keytool -printcert

Hopefully this version will be future proof as the one-liner now uses his suggestion to search/grep for a .RSA file.


Owner: CN=Whisper Systems, OU=Research and Development, O=Whisper Systems, L=Pittsburgh, ST=PA, C=US
Issuer: CN=Whisper Systems, OU=Research and Development, O=Whisper Systems, L=Pittsburgh, ST=PA, C=US
Serial number: 4bfbebba
Valid from: Tue May 25 17:24:42 CEST 2010 until: Tue May 16 17:24:42 CEST 2045
Certificate fingerprints:
SHA1: 45:98:9D:C9:AD:87:28:C2:AA:9A:82:FA:55:50:3E:34:A8:87:93:74
SHA256: 29:F3:4E:5F:27:F2:11:B4:24:BC:5B:F9:D6:71:62:C0:EA:FB:A2:DA:35:AF:35:C1:64:16:FC:44:62:76:BA:26
Signature algorithm name: SHA1withRSA
Subject Public Key Algorithm: 1024-bit RSA key
Version: 3

As you can see, still the same fingerprint.