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

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 we can do is just curl a REST end point which will spit some uglified JSON into the console, right?

Let's say we need to get a list of public bike stations in Barcelona:

curl -s

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

Yes, we 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?

We look up the station IDs we need at the offical Barcelona bicing
and pass the station IDs as parameters to jq:

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

Since we don't want all the fields in the JSON, we pass in the JSON keys for the data we 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 '.[] | select(.id==("153", "154", "339", "382","150")) | .name,.bikes,.slots'

This looks a bit better, but by default jq prints one key per line, and we want to add some formatting, so that data for one station shows in a single line. We 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 'Bikes Slots ID Address'curl -s --compressed | jq -r '.[] | select(.id==("153", "154", "339", "382","150")) | "\(.bikes)\t\(.slots)\t\(.id)\t\(.address), \(.addressNumber)"'

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

03 March 2016

Creating native dictionaries for the OSX

OSX has an integrated dictionary app which can be accessed by selecting some text in any application, right-clicking and then picking Look up from the context menu (three-finger-tap on a selected word should work too).

The OSX Dictionary comes pre-installed with several dictionaries but creating your own dictionaries or converting existing ones is surprisingly complex.

This post is an attempt to make this process easier for everyone.

Most third-party dictionaries that I use are in DSL (ABBY Lingvo) and BGL (Babylon) formats. I have collected them over the years, and have been using them both on the desktop via the open-source app GoldenDict, and on my smartphone thanks to GoldenDict for android. The OSX version of GoldenDict is still buggy, and apparently not properly maintained, so I wanted to find a way to migrate my existing dictionaries to the native OSX dictionary app.

After a bit of research I finally figured out the toolchain for converting my existing dictionaries in Babylon and Lingvo DSL formats to the AppleDict format which the OSX expects.


Auxiliary Tools for Xcode

Download the DMG for Auxiliary Tools for Xcode from You'll need to sign in with your Apple ID in order to download. If you already have an iCloud account then you can use it. Once you sign in you can use the direct link to Auxiliary Tools for Xcode 7 or use the latest version by searching for it on the Apple downloads page.

Mount the DMG file by double-clicking it in Finder. Next, As the root user create a folder at /Developer/Extras and copy the Dictionary Development Kit folder from the Auxiliary Tools into that folder.
sudo mkdir -p /Developer/Extras
sudo cp -r "/Volumes/Auxiliary Tools/Dictionary Development Kit" /Developer/Extras

Python 3

Install Python 3 via homebrew (OSX comes with Python 2.x preinstalled):
brew cask install python3

Python 3 dependencies

Install lxml and BeautifulSoup, the parsers that pyglossary depends on:
## for current user only
pip3 install lxml beautifulsoup4 --user

## system-wide, for all users
sudo pip3 install lxml beautifulsoup4


Clone the pyGlossary project to a folder on your drive:
mkdir -p ~/projects
cd ~/projects
git clone --depth 1
Next, locate the path to pyglossary.pyw — that's the script you'll need for converting the DSL file in UTF-8 encoding to AppleDict XML.

DSL to AppleDict conversion

The DSL to AppleDict sequence:
  1. DSL files come in Unicode Little Endian encoding, so the first step would be converting your DSL file from UTF-16 to UTF-8:
  2. iconv -f UTF-16 -t UTF-8 webster-original-utf16.dsl > webster.dsl
  3. Now do the actual conversion to AppleDict source format. Make sure you include the correct path to pyglossary.pyw. When the command completes (which might take several minutes if the source file is big), a new file webster.xml will be created along with some make files.
  4. ~/projects/pyglossary/pyglossary.pyw --read-format=ABBYYLingvoDSL --write-format=AppleDict webster.dsl webster.xml
  5. The generated AppleDict source file will be created in a subfolder with the same name as the source file, i.e. webster. Next, we move into that folder and do the compilation of AppleDict source to the OSX binary dictionary format:
  6. cd webster
    make install
Running make install will copy the compiled dictionary to ~/Library/Dictionaries. Restart the, open preferences (⌘ + ,), and you should see the new dictionary available in the list. Enable the corresponding checkbox to make the dictionary active.

I have created a bash script that automates the process of DSL to AppleDict conversion: Run the bash script without arguments to see usage notes.

IMPORTANT: You will need to edit the script and set the correct value of PYGLOSSARY_HOME, by default it is ~/projects/pyglossary.

Babylon BGL to AppleDict conversion

The conversion steps for BGL dictionaries:

A bash script for BGL to AppleDict is available at To get this toolchain to work I recommend reading the readme files which are included both with pyglossary and the Apple Dictionary Development Kit. I have included the most important points in the help section of the bash script for DSL.

Where to get the dictionaries?

There are literally hundreds, maybe thousands of dictionaries in DSL, Stardict, and Babylon BGL formats. A search engine query with the format and language pairs will most likely return some links where you'll be able to download the files. For example try stardict+english+spanish. The Goldendict dictionaries download page also has some useful links.

There are also a couple of command line utilities for converting between free dictionary formats: dictconv, makedict.

16 August 2012

Firebug Lite Bookmarklet for Internet Explorer

Firebug is what makes Firefox great, but how about other dysfunctional browsers like Internet Explorer? There is a way to use a stripped-down version of Firebug on IE, thanks to Firebug Lite.

To use it, just drag the bookmarklet icon below to the Internet Explorer Favorites bar.

NOTE: It might take some time to load the bookmarklet, i.e. ten, twenty seconds or even more.

14 April 2012

Linux: How to export Google Chrome passwords to CSV file

Update: A simpler method is described in this post How can I export chrome passwords?

Having spent some time googling for a way to export Chrome passwords to an external file to my surprise I could not find a straightforward solution that would work irregardless of the version of Chrome/Chromium. Finally, this page provided a hint to a solution which worked for me.

Older versions of Chrome/Chromium for Linux stored unencrypted passwords in an SQLite database under:

### Google Chrome:
    ~/.config/google-chrome/Default/Login Data

    ### Chromium:
    ~/.config/chromium/Default/Login Data

In newer versions of Chrome this file is still present, but the passwords are not there anymore - they are stored using the encrypted password storage provided by the system, either Gnome Keyring or KWallet, which means that simply dumping the tables will not work. On OSX the Chrome passwords are in the system keychain, and can be viewed from System Keychain

The method below relies on forcing Chrome to use a temporary profile folder in combination with unencrypted password storage. This approach will not affect your current Chrome profile in any way.

So, to export your passwords to a human readable text file:

  1. Connect to your Google Account in Chrome Settings so that your passwords are synched with the Google cloud storage. Make sure that you have ticked Passwords in Advanced Sync Settings.
  2. Wait for a while until the data is synched, and then close all the Chrome windows.
  3. Start Chrome using one of the two command lines below. Google Chrome has a green-red-yellow icon , while the Chromium icon is in shades of blue .
    ### Google Chrome
        google-chrome --user-data-dir=/tmp/chrome-tmp --password-store=basic
    ### Chromium
        chromium --user-data-dir=/tmp/chrome-tmp --password-store=basic
    This will launch Chrome with a custom profile folder without affecting your current profile.
  4. Setup Google Synching for the new temporary profile and wait until everything is synced from the cloud, i.e. your bookmarks appear, extensions show up, the theme is applied, etc. Verify that the passwords are restored from the Google cloud by looking under Settings → Personal Stuff → Manage Saved Passwords. If they do not appear, then wait a couple of minutes more. Note: the fastest way to get to the stored passwords page in settings is to type password in the Search box in the top right.
  5. Exit Chrome.
  6. Next, open a terminal and change to the newly created Chrome profile
    cd /tmp/chrome-tmp/Default
  7. Now, open the Login Data SQLite database using the sqlite3 command line utility and dump the logins table. For this to work, you need to have sqlite3 installed on your system.
    sqlite3 'Login Data'
  8. Next, at the SQLite prompt enter the commands below. For help on available commands type .help at the prompt.
    .mode csv               # other options are `html', `tabs', etc.
    .headers on
    .separator ","
    .output chrome_passwords.csv
    select * from logins;

Now you should have a file named chrome_passwords.csv containing all your Chrome passwords. To open it with LibreOffice, type:

libreoffice --calc chrome_passwords.csv

19 January 2012

Bookmarklet for reading Android documentation in full screen

Who likes frames? Google does. At least on the Android documentation site. I am not saying that frames are necessarily evil. There are indeed cases when they are justified, especially when it comes to documentation. Nonetheless, while reading the Android development docs I wish I had the option to collapse the top and left navigation bars.

Luckily, the left navigation panel can be re-sized by dragging the vertical border separator, but there is no way to easily get rid of the top navigation bar.

The simplest solution that came to mind was to create a bookmarklet which will reformat the page in a single click.

To use the bookmarklet, click and drag the link below to the Bookmarks (Favorites) bar in your browser.

Now, whenever you are browsing a page at you can expand the documentation pane to take the full screen, by clicking the bookmark in your Bookmarks bar, or select the corresponding item in your Bookmarks/Favorites menu.

Comments and feedback are also welcome at

25 June 2011

Bash: Run command on each line in a file

This script runs a user-defined command on each line in a text file. The filename should come as the first argument, everything following it will be interpreted as the command name with arguments, if any.

For example, if you have a list of file names saved to a file, and want to do something with them, e.g. see file details, you could run `foreach filelist.txt ls -alh`.

Long Version


if [ "$#" == "0" ]; then
    echo -e "USAGE:\n    `basename $0` <filename.txt> <cmd args...>"
    exit 1


shift 1


while read -r line <&3
 echo $args $line
 eval $args $line 
done 3<"$list"

Shorter Version — the power of xargs

Things are much simplier with xargs - it will read a list of arguments from standard input and run a command on each argument. By default arguments are separated by space, but you can specify your own separator with the -d (delimiter) option.

If you work with file names you might want to use xargs -0 to specify that the parameters are delimited by the the null separator. This is useful for example when you need to correctly handle file names containing spaces or other wierd characters. To generate the parameters with the null separators you could use find -print0 to find the files matching your criteria.

Here is an example that finds all .avi files in the current folder and print detailed info using `file` utility.

find . -iname "*.avi" -print0 | xargs -0 file

But find by itself is pretty powerful and can handle this particular use case on its own without using xargs.

find . -iname "*.avi" -exec file "{}" \;
Note that there is an important difference between the two commands: the xargs-version will only run file once passing all the parameters in one go, while find -exec will run the file command multiple times for each argument, so if the program you are running takes a while to start the performance in the second case might be significantly worse.

31 August 2010

Using Google Translate from console

If you have ever used Google Translate and wished you could do the same from console, here is a Python script that does just that.

The script will translate words and entire sentences between any language pair known to Google Translate. It will accept both text passed in as shell arguments, as well as data from standard input.

NOTE: This script stopped working after the translation API version 1 was discontinued on December 2011. See the updated script below for a working version.

NOTE: According to
Important: Google Translate API v1 was officially deprecated on May 26, 2011; it was shut off completely on December 1, 2011. For text translations, you can use the Google Translate API v2, which is now available as a paid service. For website translations, we encourage you to use the Google Website Translator gadget.
#!/usr/bin/env python
from urllib2 import urlopen
from urllib import urlencode
import sys
import os

# The google translate API can be found here:

# Language codes are listed here:

if len(sys.argv) < 3:
    name = os.path.basename(sys.argv[0])
    print '''
    %s en es lovely spam
    %s es en < file.txt

Available language codes are listed here:
''' % (name,name)

## hack to be able to display UTF-8 in Windows console
if sys.platform == "win32":
    ## set utf8 console
    if not sys.stdin.encoding == 'cp65001':
        os.system('chcp 65001 > nul')
    class UniStream(object):
        __slots__= "fileno", "softspace",
        def __init__(self, fileobject):
            self.fileno= fileobject.fileno()
            self.softspace = False
        def write(self, text):
            if isinstance(text, unicode):
                os.write(self.fileno, text.encode("utf_8"))
                os.write(self.fileno, text)
    sys.stdout= UniStream(sys.stdout)
    sys.stderr= UniStream(sys.stderr)


if len(sys.argv) > 3:
    text=' '.join(sys.argv[3:])

params=urlencode( (('v',1.0),
('langpair',langpair),) )
end_idx=translation.find('"}, "')
sys.stdout.write(translation + '\n')

This is the updated script that uses the web API. Should work after December 2011.

#!/usr/bin/env python
import sys
import os
import urllib2
from urllib import urlencode
import cookielib
import re

# The google translate API can be found here (***NOT OPERATIONAL SINCE DECEMBER 2011***):

# Language codes are listed here:

if len(sys.argv) < 3:
    name = os.path.basename(sys.argv[0])
    print '''
    %s en es lovely spam
    %s es en < file.txt

Available language codes are listed here:

''' % (name,name)

## hack to be able to display UTF-8 in Windows console

def fix_win32_console():
    ## set utf8 console
    if not sys.stdin.encoding == 'cp65001':
        os.system('chcp 65001 > nul')
    class UniStream(object):
        __slots__= "fileno", "softspace",
        def __init__(self, fileobject):
            self.fileno= fileobject.fileno()
            self.softspace = False
        def write(self, text):
            if isinstance(text, unicode):
                os.write(self.fileno, text.encode("utf_8"))
                os.write(self.fileno, text)
    sys.stdout= UniStream(sys.stdout)
    sys.stderr= UniStream(sys.stderr)

if sys.platform == "win32":


if len(sys.argv) > 3:
    text=' '.join(sys.argv[3:])

# sample browser request

url=base_url + '?' + params

cookiejar = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
opener.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1018.0 Safari/535.19'),
                    ('Referer', '')
response =
matcher ='\[\[\["(?P<human_readable_chunk>[^")]*)', translation)

Save the script to a file such as and run it as follows (assuming you have Python in your path):

    python en es Nobody expects the Spanish Inquisition

The first two parameters are the language codes. A list of codes known to google translate is available here: For some reason, not all of the listed codes are actually accepted, for example, bo for Tibetan

To pipe a text file through the script:

    python en es < myfile.txt

It is also possible to enter multi-line text directly from the console. To do so, call the script with the language codes only, i.e:

    python en es

Enter your text and use the Enter key to start a new line. When you are done, press CTR+d (on Linux) or CTR+z followed by Enter (on Windows).

Note: On Windows input in other languages than English is not going to work. This is due to poor support of Unicode input in cmd.exe. On Linux international input works fine, provided that the console is UTF-8.

Keep in mind though that google has a limit on the size of text to be translated.

Console Google Translate — curl-based version

As an alternative, here is a bash script which uses curl and sed. Updated to work via Google Translate Web API.

#! /bin/bash

       $0 en es Lovely spam!
Some codes: en|fr|de|ru|nl|it|es|ja|la|pl|bo
All language codes:"

if [ "$#" == "0" ]; then
    echo "$USAGE"
    exit 1


shift 2

UA="Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.2) Gecko/20040803"
curl  --data-urlencode "text=$QUERY" -A $UA -s -g -4 $URL | sed 's/","/\n/g' | sed 's/\]\|\[\|"//g' | sed 's/","/\n/g' | sed 's/,[0-9]*/ /g'

28 August 2010

Linux console online dictionary lookup

I often need to lookup words in various online dictionaries, but in many cases I would prefer to get the results right in the console, instead of having to launch the browser, type in the URL and wait for the page to load.

For example, here is a bash oneliner that translates an English word to Spanish right in the console:

Wordreference English-Spanish: 
curl -j -s -A "Opera/9.60 (J2ME/MIDP; Opera Mini/4.2.13337/458; U; en) Presto/2.2.0" "`echo $* | sed 's/ /%20/g'`" | html2text -utf8 | less -R

Wordreference Spanish to English:
curl -j -s -A "Opera/9.60 (J2ME/MIDP; Opera Mini/4.2.13337/458; U; en) Presto/2.2.0" "`echo $* | sed 's/ /%20/g'`" | html2text -utf8 | less -R

Merriam Webster Online English Dictionary: 
curl -j -s -A "Opera/9.60 (J2ME/MIDP; Opera Mini/4.2.13337/458; U; en) Presto/2.2.0" "`echo $* | sed 's/ /%20/g'`" | html2text -utf8 | less -R

Wikipedia (EN):
curl -j -s -A "Opera/9.60 (J2ME/MIDP; Opera Mini/4.2.13337/458; U; en) Presto/2.2.0" "`echo $* | sed 's/ /%20/g'`" | html2text -utf8 | less -R 

Usage: Save the required script to a file, make it executable (chmod +x webster), and then type the script name from the console with the word(s) you need translated as arguments.

Instead of creating a separate script for each dictionary it might be more practical to add the scriptlets as aliases in your .bashrc file, e.g:

alias webster="curl -j -s -A "Opera/9.60 (J2ME/MIDP; Opera Mini/4.2.13337/458; U; en) Presto/2.2.0" "`echo $* | sed 's/ /%20/g'`" | html2text -utf8 | less -R"
Make sure you have curl, html2text , sed, and less installed.

A similar result can be achieved by using some console browser like lynx or w3m. Install w3m:

sudo apt-get install w3m # for Ubuntu
sudo pacman -S w3m       # Archlinux

Create a wrapper script which includes the URL:

echo 'w3m "$*"' > ~/bin/en2es
chmod +x ~/bin/en2es

Now the script can be run like this:

en2es word of mouth

The advantage in this case is that you can use all the standard browser features, like clicking links, etc.

30 April 2010

Bash oneliners or helpful aliases for your .bashrc

Useful bash oneliners that might or might not be worth including as aliases in your ~/.bashrc file.

Bash Oneliners
grep -v "^#" $* | grep -v "^$"
print file contents excluding comments starting with # and empty lines
netstat -tpauln
print open TCP connections *and* application names
find . -maxdepth 1  -type d  -exec du -sh {} \; | sort -hr
print sorted directory sizes starting with the biggest
find . -maxdepth 1 -mindepth 1 -type d -print0 | xargs -0 du -sh | sort -hr
same as above, but supposedly more efficient for lots of files
help test | less
does not do much work on itself but it is good reading
[ -n $SOMEVAR ] &&  echo "IS_NOT_EMPTY" || echo "IS_EMPTY"
execute first command on empty string, or execute second command otherwise (the Python way)
mkdir $(echo {01..22}spam)
create folders 01spam, 02spam, 03spam, etc.
cp filename{,.bak}
create backup of file
rerun previous command
sudo !!
rerun previous command as root
python -m SimpleHTTPServer
run web server for current dir on port 8000 (Python 2.x version)
python -m http.server
run web server for current dir (Python 3 version)
:w !sudo tee %
write file in vim as root
ssh-copy-id remote-machine
copy rsa/dsa key to remote machine for public authentication
ffmpeg -f x11grab -s wxga -r 25 -i :0.0 -sameq /tmp/out.mpg
record current desktop to mpeg file
echo -e ${PATH//\:/\\n}
string replace with bash (the example replaces colon with end-of-line
curl -O
download file to local file forex.xml
tr -dc ' -~' < /dev/urandom | head -c 20
generate random string
echo $(($RANDOM % 100))
generate random number in range
sudo find . -user root -exec chown spamneggs {} \;
find all files owned by root and change owner to spamneggs
function mcd {
  mkdir ${1} && cd ${1}  
a ~/.bashrc shortcut to make a directory and move into it.
function catw {
cat `which "${1}"`  
a ~/.bashrc shortcut for typing cat `which script`
function vimw {
vim `which "${1}"`  
a ~/.bashrc shortcut for typing vim `which script`; you get the idea...
See also:

15 April 2010

Running a command recursively on all files in a directory tree

Windows solution
Here is a script which calls mplayer on every file in a directory including subfolders:

The script will work on dirs containing spaces and non-ascii characters since all file names are converted to short dos names (via the `~s` modifier).
  set mplayer=z:\path_to_mplayer\mplayer.exe
  for /f "delims=" %%f in ('dir /b /s "%cd%"') do (%mplayer% "%%~sf")
Linux bash solution
The bash shell solution is much easier to read than the windows one:
  for f in `find $cwd -type f -iname "*.mp3" `; do
    mplayer $f

A Better Solution

An alternative solution for both Windows and Linux would be to create a playlist file first, and then run a single mplayer instance with the -playlist switch:
Linux bash
  find $pwd -type f -iname "*.mp3" > /tmp/allfiles.m3u
  mplayer -playlist /tmp/allfiles.m3u
Windows Batch
  set mplayer=z:\path_to_mplayer\mplayer.exe
  set playlist=%TEMP%/mp3playlist.m3u
  dir /b /s "%cd%" | find /I ".mp3" > "%playlist%"
  %mplayer% -playlist "%playlist%"
Shortest solution
  mplayer $(find . -iname "*.mp3")

27 November 2009

VIM usability: my .vimrc

My .vimrc compiled from various Internet sources. The goal was to make vim more user-friendly for someone who is familiar with popular shortcuts like Ctr+C for copy and Ctr+V for paste, but still retaining most classic vim shortcuts. Since Ctr+V cannot be used for vertical block selection it still can be done with Ctr+Q if your OS allows it.

28 October 2009

Entering special characters in Linux

Occasionally there is a need to enter special characters which are not on the keyboard, for example, an M-dash, ("—") or and N-dash ("–").

This solution works on all recent xorg versions, so it should work on all modern Linux distros.

  1. Press Ctr+Shift+U.
  2. Release U while still holding Ctr+Shift.
  3. Enter the four digit character code, e.g. 2013 for an m-dash, or 2014 for a n-dash.
Some special characters:
Unicode character code (HEX)
Special Character
2013 – (en-dash)
— (em-dash)


You can find a list of some character codes here:

30 September 2009 Bookmarklet

This bookmarklet opens a Word Reference popup window for the currently selected word on a page. Works in the same way as the Google Translate bookmarklets.

Word Reference Es-En
05/2010: updated to work on pages with frames


21 September 2009

Google Translate Popup Bookmarklet

These bookmarklets open a Google Translate popup for the currently selected text on a page. The only difference from the standard google translate bookmarklets is that these bookmarklets will also work on pages that use frames or inline frames, for example in gmail.

To use a bookmarklet drag the link (do not click) to you Favorites toolbar. Once you have added the icon to your toolbar, select some text (e.g. in Spanish) on a page and then click the bookmark icon.

To modify the language pair, edit the language code in the bookmarklet source from es|en to whatever language you want. Use auto to autodetect the source language.

Google Translate En-Es
Google Translate Es-En
Google Translate Any-En (autodetect)
Google Translate Any-Es (autodetect)

To see how this works select some text on this page and then click the link Google Translate En-Es to get a Spanish translation in a popup window.

To get more google translate buttons for more languages go to the google's own page at


28 May 2009

M4AtoMP3: Convert M4A files to MP3

I wanted to convert some M4A files to MP3, and found some examples of how to do it: Convert iTunes M4A files to MP3 on Linux, and especially Howto:convert aac/mp4 to wav/mp3/ogg on Linux.

The second link was close to what I wanted, and the script almost worked, but I wanted something even simpler, so here is the simplest script that worked for me. It converts all .M4A files in the current directory to MP3.

# Usage: run without arguments from the folder containing M4A files
# Uses faad and lame (sudo apt-get install faad lame)
shopt -s nocaseglob

for file in *.m4a ; do
  if [ -e "${file%%.*}.mp3" ]; then
    echo "file ${file%%.*}.mp3 already exists! skipping!" ;
  faad -o - $file | lame - "${file%%.*}.mp3" ;

22 May 2009

Screen Quick Howto

What is screen?
man page: "Screen is a full-screen window manager that multiplexes a physical terminal between several processes (typically interactive shells)." Here is a screen screen tutorial.
Screen quickref
Most of the data below has been taken from the screen quick reference.
Change to last-visited active window
C-a C-a (commonly used to flip-flop between two windows)
Change to window by number
C-a <number> (only for windows 0 to 9)
Change to window by number or name'
C-a <number or title>
Change to next window in list
C-a n or C-a <space>
Change to previous window in list
C-a p
Split current screen session into two regions
Remove current region
C-a X
remove all regions but the current one
C-a Q
Switch between displayed regions
Create new session in split region
C-a c
Return to a single region
C-a Q
C-a d
Detach and logout (quick exit)
C-a D D
Enter copy mode
C-a [ (also used for viewing scrollback buffer) and with C-]
C-a ]
Rename current window
C-a A (note the uppercase 'A'!)
Console commands
Detach attached session
screen -D
Detach attached screen session (possibly running in another terminal) and reattach in current terminal
screen -Dr
Detach specific screen session (when more than one sessions are running)screen -D 14493.ssh2others
Move cursor to beginning of lineControl+a (release Control) + a