The Big Browser

M y    b r a i n    h u r t s  !                                           w e                 r e a l l y                 t h i n k                   w h a t                y o u             k n o w

27 March 2021

Bulk convert APE (MonkeyAudio) files to FLAC recursively from command line

A oneliner that will search recursively for all .APE files under the current folder (ie .) and convert them to .FLAC. This will handle correctly file names containing special characters such as single and double quotes, brackets, etc.
find . -type f -iname "*.ape" -exec sh -c 'ffmpeg -i "${1}" "${1%.*}.flac"' _ {} \;
In this way you can convert between any format that ffmpeg can handle, for exaple convert all FLAC files to MP3:
find . -type f -iname "*.flac" -exec sh -c 'ffmpeg -i "${1}" "${1%.*}.mp3"' _ {} \;

29 November 2020

Convert all MOV video files in the current folder to MP4

Convert a single MOV video file to MP4 format:

  ffmpeg -i my_video.mp4
Convert all MOV videos in the current folder and sub-folders to MP4 and delete the orignal .MOV files: For Linux or Mac, or on Windows under msys, cygwin, cmder etc.
for video in `find . -iname "*.mov"` ; do
    ffmpeg -i "${video}" "${video%.*}.mp4" && rm "${video}"
NOTE: While the script above might work with most files it will fail with files containing special characters, such as spaces, single or double quotes, slashes, dashes or !#& and others. This is a more robust version that will handle correctly special characters in file names:
find . -iname '*.mov' -print0 | xargs -0 -I {} ffmpeg -i '{}' '{}.mp4' && rm '{}'
And another version of the same that avoids the use of xargs by using a sub-shell:
find . -type f -iname "*.mov" -exec sh -c 'ffmpeg -i "${1}" "${1%.*}.mp4" && rm "${1}" ' _ {} \;
If ffmpeg is not present on your system install it with apt install ffmpeg (on Linux) or brew install ffmpeg on Mac.

22 November 2020

CSS Style Sheet HTML Preview Generator (python script)

How do I see an HTML preview of every single CSS rule defined in a CSS file?

There is no fixed way to do it, especially if your CSS style sheets make abundant use of absolute and fixed positioning. This script below is a quick and dirty attempt to generate HTML tags for all the rules defined in a CSS file. If the rule is defined for a known HTML tag then that tag is rendered as itself, otherwise a div tag is created.

The script does not cover every possible scenario and only supports the most common CSS constructs. It wraps all fixed CSS rules into a dedicated iframe in order to prevent elements from overlapping. You can disable wrapping fixed elements into frames by passing --no-frames.

If you have a large CSS file the HTML generation can take up to several minutes since nested rules are iterated recursively.

⚠️ For complex CSS style sheets (1MB+) the generated HTML can cause the browser to freeze or rendering to take a signficant time even on a performant computer. You have been warned!


The CSS preview generator depends on the cssutil python module which can be installed with:

pip3 install cssutils

You are welcome to fork, improve and provide feedback.

Usage mystyles.css -o mypreview.html
For more options run with the -h or --help switch.

Example output

Python CSS preview generator script

16 October 2017

Barcelona city bikes availability: a console REST client with curl and jq

How do you consume a REST api in the terminal? All you can do is just curl a REST end point which will spit some uglified JSON into the console, right?

Let's say you want to get a list of public bike stations in Barcelona:

curl -s

Hmmm, that's not very readable... Can you do better than this?

Yes, you can!

Meet jq — a full-fledged console JSON parser, as powerful as awk but for JSON.

Available in standard linux repos:

sudo apt install jq

as well as in homebrew on Mac:

brew install jq

Now we can display the list of all bike stations in Barcelona with JSON pretty-printing and colorization:

curl -s | jq

Now, this is more readable. But how about filtering for specific bike stations, say the ones closest to our daily destinations?

I pulled the station IDs at offical Barcelona bicing
and pass the IDs as parameters to jq:

curl -s --compressed | jq -r '.stations[] | select(.id==("153", "154", "339", "382","150"))'

Since I don't want all the fields in the JSON, I pass in the JSON keys for the data I want to keep.

Get bikes by station IDs, and extract station address, number of bikes, and number of parking slots:

curl -s --compressed | jq -r '.stations[] | select(.id==("153", "154", "339", "382","150")) | .streetName,.bikes,.slots'

This looks a bit better, but by default jq prints one key per line, and I want to add some formatting, so that data for one station shows in a single line. I can use jq string interpolation to achieve this. Here is the final version which prints our data in a tabular format (available bikes, parking slots, station id, and address):

echo 'AVL\tEMP\tSID\tADR'
curl -s --compressed | jq -r '.stations[] | select(.id==("153", "154", "339", "382","150")) | "\(.bikes)\t\(.slots)\t\(.id)\t\(.streetName), \(.streetNumber)"'

And here is the final result:

And, finally, what's the point of adding the --compressed parameter to curl?

Setting --compressed is equivalent to setting --header 'Accept-Encoding: gzip,deflate' — as a result the server will compress the output with gzip or deflate (if capable of compression), and curl will decompress the response on the fly, which will make the result appear faster since less bytes will be sent over the network.

13 July 2016

Simple webserver with twisted

The Python oneliner webserver python -m SimpleHTTPServer (for Python 2.x) or python -m http.server (for Python 3.x) is useful in many scenarios, but sometimes it simply does not cut it because it is meant for development only, is not secure, and is single-threaded.

A better oneline webserver comes with Twisted, the library that the original bittorrent reference implementation was written in.
Installing twisted for the current user only:

pip install twisted --user

Installing twisted system-wide:

sudo pip install twisted

Once installed you can run the default twisted webserver with a command like twistd -n web --path . where the dot represents the current folder. Replace with an absolute path if you need.

The version below additionally displays the internal and external IP addresses, so that you can launch the server and instantly connect to it by entering the displayed IP on your mobile devices or another computers in the local network.

echo 'IP Address:' $(ifconfig | sed -En 's/;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'):8080
echo 'External IP:' $(wget -qO -):8080
twistd -n web --path .

In order to be able to connect via the external IP you'll need to set up port forwarding on your router as described at