Getting the Git commit id of a Gerrit Change Set

Oddly enough, Gerrit doesn’t report the Git commit id of its Change Sets.

The only way I found to get that piece of information is to use its SSH interface, using the query command.

The syntax is this:

ssh -p 29418 user@gerritHost gerrit query --current-patch-set <ChangeId>

replacing 29418 with the port you normally use to contact Gerrit via SSH.

That will display a number of properties about the Change Set, including the revision parameter which is the extended version of the Git commit id.

You can use the --format JSON option if you want to get a JSON representation of the same data, or you can get the short commit id using for example:

ssh -p 29418 user@gerritHost gerrit query --current-patch-set <ChangeId> \
cut -d':' -f2 | cut -c2-7

A simple script to delete multiple keys from redis all at once

When developing, you sometimes want to delete a bunch of redis keys all at once. The KEYS command gets half of the job done, but what’s missing is a convenient way to wire it to the DEL command.

In these cases, (again, when developing, as the KEYS command is check-all-keys-in-database-slow) I often rely on this script:

#!/bin/bash
#
# A simple script to delete a bunch of keys from redis all at once.
#
# Don't use it in production!!!1!1!one

read -p "redis port to connect to? [6379] " redis_port

if [[ "${redis_port}" == "" ]]; then
    redis_port="6379"
fi

if [[ ${redis_port} =~ ^[0-9]+$ ]]; then
    while true; do
        read -p "keys to delete (wildcard accepted, e.g. user:foo:bar:*): " pattern
        # read all keys into a white space separated array
        IFS=$'\r\n' GLOBIGNORE='*' :; matches=($(redis-cli --raw -p ${redis_port} keys "${pattern}"))

        # list all matches
        echo "Matching keys:"
        matching_keys=0
        for line in ${matches[@]}; do
            echo $line
            matching_keys=$((matching_keys+1))
        done

        if [[ "${matching_keys}" -eq 0 ]]; then
            echo "No keys match your query, nothing to do."
        else
            read -p "Keys that will be deleted: ${matching_keys}. Really delete? [y/N] " confirm
            case ${confirm} in
                [yY]*)
                    echo -n "Keys deleted: "
                    redis-cli --raw -p ${redis_port} del "${matches[@]}"
                    ;;
            esac
        fi
    done
else
    echo 'must specify a valid port number'
    exit 1
fi

The nice thing about it is that it shows you what keys will be deleted before deleting them, so you have a chance of not screwing up your own DB! 🙂

Use it at will, but please, don’t use it in production!

Usage is straightforward, just chmod +x the script, and call it. Use Ctrl-C to exit the script.

sudo asks for password even if NOPASSWD is set in /etc/sudoers

TL;DR when a script is not marked as executable and you try to run it with sudo, you don’t get the usual -bash: myScript.sh: Permission denied message, you are prompted for a password instead!

This one was very frustrating.

What I wanted to do was to make a user (let’s call him bran) able to execute a specific script (let’s call it /home/hodor/calm_down.sh) without having to provide his password, because the script will be executed by an automated tool (Jenkins).

I reached back to my earlier post about sudo, and updated the /etc/sudoers file so that its User privilege specification section looked like this:

root    ALL=(ALL) ALL
bran    ALL=(hodor)  NOPASSWD:  /home/hodor/calm_down.sh *

The last line gives user bran the ability to run /home/hodor/calm_down.sh as user hodor passing it any number of parameters (*) without having to provide his password (NOPASSWD:).

Saved it, su‘ed into bran, ran

bran@laketower:~$ sudo -u hodor /home/hodor/calm_down.sh "it's ok"

aaaaand…

[sudo] password for hodor: 

d’oh.

I checked the syntax in /etc/sudoers, and it was ok.

I checked whether any of the declarations that followed in /etc/sudoers could override the line I set for bran and hodor, none to be found.

Heck, I even put that line as the last line, so no line could override it. Nothing.

After a good hour of googling around and finding nothing, I remembered that the script is in a Git repository for which I just checked out a different branch. As it turned out, the script lost its executable bit.

So I set the executable bit again, as user hodor:

hodor@laketower:~$ chmod +x calm_down.sh
hodor@laketower:~$ logout
root@laketower:~# su - bran
bran@laketower:~$ sudo -u hodor /home/hodor/calm_down.sh "it's ok"
hodor.
bran@laketower:~$

it worked!

I’m sure there’s a legitimate security concern for this behavior, but dang! was this hard to figure out!

ForkedBooter steals window focus on Mac OS while Maven is running

This is about running Maven, specifically.

For most Java applications, any of the solutions from this question on StackOverflow should work.

It’s a matter of passing -Djava.awt.headless=true to the Java process, which can be done for all Java processes by saving that option to a variable named JAVA_TOOL_OPTIONS in your .bashrc.

That’s fine as long as you have direct control over the Java process, which is not the case with Maven.

In my case, it was the Failsafe Maven Plugin that caused that annoyance, but some were experiencing the same behavior with an old version of Surefire. The following snippet fixes both.

In your pom.xml, change your existing <plugin> definitions so that they look like this (the important lines are highlighted):

<!-- this is inside your <project><build><plugins> block -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${maven.surefire.plugin.version}</version>
    <configuration>
      <includes>
        <include>**/unit/**/*Test*.java</include>
      </includes>
      <!-- prevent the annoying ForkedBooter process from stealing 
        window focus on Mac OS -->
      <argLine>-Djava.awt.headless=true</argLine>
    </configuration>
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>${maven.failsafe.plugin.version}</version>
    <configuration>
      <!-- prevent the annoying ForkedBooter process from stealing 
        window focus on Mac OS -->
      <argLine>-Djava.awt.headless=true</argLine>
      <includes>
        <include>**/integration/**/*Test*</include>
      </includes>
    </configuration>
    <executions>
      <execution>
        <goals>
          <goal>integration-test</goal>
          <goal>verify</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

Done!

I added this reply to stack exchange as well, but maybe this post will be easier to find (as that question already already had an accepted answer when I replied, and it doesn’t work for Maven). We’ll see!

Fix out of sync subtitles with Python!

This is an update of my old post from a couple of years ago.

[Edit – October 2015]: I created an in-browser version of subslider, called subslider.js. Just visit this page and follow the instructions, or read this blog post if you want to know more about it!

After using that script quite a few times, and loving it, I decided to give it a facelift and add the one feature that I’ve been wishing it had for all this time: the option to just tell it the timestamp of the first dialog without performing any math 🙂

Yeah, it’s simple math, but having to use base 60 means more brain CPU time wasted (and above all, it means more time separating me from my movie!).

I also moved the code to GitHub, so you can find it here: SubSlider. And this is the direct link to the python script, for the impatient.

The old way of specifying offsets using +/- has been replaced my a more argparse-standard system of flags. Also, the new feature I mentioned above can be used by running the script like this:

python subslider.py -s 1:23,450 MySubFile.srt

assuming your subtitles file is called MySubFile.srt and assuming that the first dialog in the movie takes place at 1:23,450. This time, there’s an “interactive” dialog that asks you to choose the first line among the first 10 lines in the .srt file. I added it because sometimes you get the equivalent of opening titles in the .srt, and that doesn’t help when you’re synchronizing.

If you want to get a different number of lines, you can simply change the LINES_TO_SHOW variable at line 43 to whatever number you prefer.

As always, feel free to contribute 🙂

Another wallpaper changer for Gnome and Unity

The previous wallpaper changer that I wrote in Python served me well for the last 2 years, but sometimes it would get stuck with some wallpapers: of the 200 pictures I have in my wallpapers folder (mostly taken from the paper wall), some were definitely being shown more often than others. Has the script developed a taste? Probably! 🙂

So this time I decided to put together something very quick, but that does a better job at never showing the same picture twice before all pictures in the folder have been set as desktop background.

It comes as a single bash script, there’s no configuration file to set, it picks pictures from a single folder (whereas the Python version could use several), and it moves files to a folder called shown when setting them as desktop background. Not very elegant, but it gets the job done!

Here it is; you can set your wallpapers folder and the refresh interval at the highlighted lines.

#!/bin/bash
#
# WallpaperChanger.sh
# Copyright 2014 Michele Bonazza michele@michelebonazza.com
#
# A simple script to automatically change your wallpaper in Gnome.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

WALLPAPERS_FOLDER=/home/path/to/your/wallpapers
REFRESH_INTERVAL=$((5 * 60)) # change every 5 minutes
MODE="zoom" # one between none, centered, wallpaper, scaled, stretched, zoom, spanned

# Changes the desktop background, and moves it to the "shown" folder so that it's
# not shown again before all wallpapers in the folder have been used.
# arg1 the file name of the file to be set as new background; must be in the
#      current folder
function change_wallpaper() {
  mv $1 shown
  gsettings set org.gnome.desktop.background picture-uri file://$WALLPAPERS_FOLDER/shown/$1
  gsettings set org.gnome.desktop.background picture-options $MODE
}

# Echoes the next wallpaper to be set, picked at random among images in the
# configured folder
function get_next_wallpaper() {
  find . -maxdepth 1 -type f -name "*.png" -o -name "*.jpg" -o -name "*.gif" -o -name "*.jpeg"| shuf -n 1
}

mkdir -p $WALLPAPERS_FOLDER/shown
cd $WALLPAPERS_FOLDER

while true; do
  NEXT_WP=$(get_next_wallpaper)
  
  # have we used all wallpapers?
  if [[ "$NEXT_WP" == "" ]]; then
    # yes, chdir to shown, and move them all back to the parent folder
    cd shown
    # move them to parent folder
    find . -maxdepth 1 -type f -name "*.png" -o -name "*.jpg" -o -name "*.gif" -o -name "*.jpeg" | xargs mv -t ..
    cd ..

    # check again
    NEXT_WP=$(get_next_wallpaper)

    if [[ "$NEXT_WP" == "" ]]; then
      echo "no wallpapers found in $WALLPAPERS_FOLDER, will check again in $REFRESH_INTERVAL seconds..."
      sleep $REFRESH_INTERVAL
      continue
    fi
  fi
  
  echo "changing background to $NEXT_WP"
  change_wallpaper $NEXT_WP
  sleep $REFRESH_INTERVAL
done

As always, I’ve also added this to my pastebin.

Save it as wallpaper_changer.sh, make it executable

chmod +x wallpaper_changer.sh

and add it to your “Startup applications” list, which can be found in Ubuntu’s main menu (the one you use to log out/shut down the computer), or can be brought up from a terminal using

gnome-session-properties

Click “Add”, use whatever name you want and browse to the wallpaper_changer.sh script (wherever you’ve saved it).

Sometimes I found that “Startup applications” doesn’t work: make sure that after having added your script and closed the window you can see an entry called wallpaper_changer.sh.desktop in the output of

ls -l ~/.config/autostart

If it’s not there, remove the entry and try again (I know, I know. The alternative is to fiddle with Upstart or init.d so if you want a GUI, that’s better than nothing!)

You can also change the effect to apply to your wallpapers at line 23 in the script.

Enjoy your new desktops! 🙂

Create a list of movies to watch with Python and Urlist

I usually like to keep lists of movies to watch, books to read, games to play on Google Keep, mainly because it comes with a widget that looks nice on my phone. Its sharing capabilities though are, well, nonexistent. Yes, you can email a list with a bullet point for each entry but it ends there.

Since I wanted to share a list of movies to watch with my wife, I resorted to Urlist. It’s a neat, straight-to-the-point tool that’s good for sharing links with friends, collaborators, anybody.

I wish they had an API available, so that this post could have been about a tool that automatically creates lists for you (heck, I could even write a simple chrome extension!), but so far there’s none.

Our list is going to have, for every entry, the vote that the movie got on IMDB, a brief summary of its plot and cast. If any of them attracts your SO’s attention, (s)he can just click to see further info about the movie 🙂

The script requires BeautifulSoup and Requests, 2 awesome libraries to scrape the web.

To install them, you can use either pip:

sudo pip install beautifulsoup4 requests

or easy_install:

sudo easy_install beautifulsoup4 requests

Create the list on Urlist, launch the script:

python scrape_IMDB.py

and for every movie you want to add:

  1. search it on IMDB
  2. copy the URL
  3. paste the URL on Urlist to add an entry
  4. paste the URL on the console where the script is running
  5. copy the output of the script
  6. back to Urlist, hit edit and paste what you copied

Here’s the script (you can download it from pastebin):

from bs4 import BeautifulSoup
import requests

done = False

while not done:
  try:
    url = raw_input("IMDB URL: ")

    # get the IMDB page
    r = requests.get(url)
    data = r.text

    # and parse it with BeautifulSoup
    soup = BeautifulSoup(data)

    # the td containing what we're looking for
    td = soup.find('td', {'id': 'overview-top'})
    rating = td.find('div', {'class': 'star-box-giga-star'}).string
    plot = td.find('p', {'itemprop': 'description'}).string
    # the div containing the main actors in the cast
    actors = td.find('div', {'itemprop': 'actors'})
    stars = ', '.join([actor.string for actor in actors.find_all('span', {'class': 'itemprop', 'itemprop': 'name'})])

    print '*%s* - %s. %s' % (rating.strip(), stars, plot)
  except KeyboardInterrupt:
    done = True
print
print 'bye!'

It’s super simple! It gets the page, finds the HTML source for what we’re looking for, and prints it out as formatted text that’s good for Urlist.

The way you find items with BeautifulSoup is relatively similar to what you do with jQuery: you look for elements in the DOM that contain what you’re looking for (to find what they are, just use your browser’s inspector… on Chrome, right click on the text and choose “Inspect element…” to see where it is in the DOM), and manipulate them as strings or arrays of strings.

Easy enough!

Disable touch input for a Wacom Bamboo tablet using a Unity launcher (or a Gnome launcher)

I love my Wacom Bamboo graphics tablet, and I really appreciate the fact that it just works in Ubuntu. Palm rejection sort of works, but that “sort of” drives me crazy when I’m using the pen and trigger scrolling by resting my hand on the tablet. I couldn’t find a quick way to disable touch input, something that I can do from a nice GUI window in Mac OS.

After searching some tool to do that, I found the very powerful xsetwacom command, and wrote a very simple script that enables/disables touch.

It goes like this:

#!/bin/bash

DEVICE_ID=$(xsetwacom --list devices | grep TOUCH | egrep -o "id\: [0-9]+" | cut -d" " -f2)

if [[ "off" == $(xsetwacom get $DEVICE_ID touch) ]]; then
    xsetwacom set $DEVICE_ID touch on
else
    xsetwacom set $DEVICE_ID touch off
fi

(should have used awk @line 3, but sometimes I get lazy when writing silly scripts)

Save this file on your user’s home calling it wacom_toggle_touch and make it executable (chmod +x wacom_toggle_touch).

Everytime you run the script, it toggles touch on the tablet. Very neat. But I wanted to just have a graphical button to click, so I created a gnome launcher that just does that; here it is:

[Desktop Entry]
Encoding=UTF-8
Name=Wacom Bamboo Touch
Comment=Toggles touch on a Wacom Bamboo Tablet
Exec=/bin/bash "/home/myuser/wacom_toggle_touch"
Icon=/usr/share/icons/Faenza/devices/scalable/input-tablet.svg
Categories=Application;
Version=1.0
Type=Application
Terminal=0

Name this file wacom-toggle-touch.desktop (the .desktop part is important) and save it to either /usr/share/applications/ or ~/.local/share/applications/, depending on whether you want all users to access the script or only your current user.

I use the cool Faenza theme for my icons, so that explains the icon path @line 6. Here’s the icon if you don’t want to use the theme but you’re looking for an icon that just gets the job done. Download it to some folder and update the path accordingly in the launcher. Also, be sure to update the path to the script @line 5 (for some reason using ~ for your user’s home doesn’t work, you have to type the extended /home/your_username path).

When you’re done, drag the wacom-toggle-touch.desktop file to your Unity bar (I actually use Docky instead, it makes switching between Mac OS and Ubuntu a lot easier on my poor brain) and just click it everytime you want to toggle touch mode!

The same process should work for Gnome as well, just drag the .desktop file to wherever launcher bar you want (assuming Gnome still has launcher bars, they kind of lost me after Gnome 3 so I don’t know).

Could not open the requested socket: Address already in use. Restart Jetty from Eclipse on Mac OSX

I am used to hit on the Play button in Eclipse like hell when developing server apps, so I ran into this issue pretty quickly.

When you’re working with Google App Engine on Mac OSX, pressing that familiar green button after having deployed the app once makes Eclipse complain as in the title. The stop button is grayed out (as it’s controlling the latest instance of Jetty, which didn’t start) and you can’t launch your app without restarting Eclipse.

So, to kill the old Jetty instance you just open a terminal and type:

lsof -i TCP:8888 | grep java | grep LISTEN

Where 8888 is the port on which Jetty is listening (it could be 8080 or something else depending on your configuration), and the first grep is just to stay on the safe side (you don’t want to kill something else). If you’re sure that there’s nothing else listening on that port, just omit it.

The output will be something like

java    33873 myusername   68u  IPv6 0xffffff801a2c1510      0t0  TCP localhost:ddi-tcp-1 (LISTEN)

Then, just type

kill -15 33873

where 33873 is the number in the second column in the output of the previous command.

You can then run the project from Eclipse.

My routine is to keep a terminal window open and just run this one-liner when I run into the error:

kill -15 $(lsof -i TCP:8888 | grep java | grep LISTEN | awk '{ print $2 }')

which does exactly the same thing, but in an automated fashion… it’s just an arrow_up away! 🙂

Change page styles with Greasemonkey/Tampermonkey

This is not a guide, as you can find plenty of them on the web (well, at least for Greasemonkey)…

This is more of a quick and dirty solution to the problem “I just want this thing to be bigger/smaller/a different color” for some web page, and I’m highlighting the word “dirty” here 🙂

I’ll take feedly as an example.

I’m enjoying feedly as a replacement for Google Reader, but I can’t stand its oh-so-narrow central frame when I’m on a 1080p 24” screen.

This is how I “fixed” that.

First, you’ll want to produce the final result you’re aiming for with chrome/firefox developer tools; in Chrome:

  1. right-click on the element whose look you want to change and choose “Inspect element”
  2. move the mouse pointer up and down in the developer tools frame until you see a blueish highlight over the element you want to edit
  3. take note of the element’s type (a <div>, a <p>, a <span>, an <img>, whatever it is) , id or class
  4. use the developer tools to change its looks (just add a custom style on the right under element.style)

Google’s official tutorial on the subject is here.

Once you’ve got a decent looking page (in my case I changed some width and max-width attributes) you’re ready to create a greasemonkey/tampermonkey script that automatically applies those changes for you when you visit that page.

First, install greasemonkey or tampermonkey.

Then, create a new script (tampermonkey has a small icon with a page and a green plus on the top bottom right corner). In the header, the important tag is @match, which tells tampermonkey which pages this script must apply to (in my case, http://cloud.feedly.com/*).

Then, you can copy & paste this piece of code (that I found on the web, it’s used by many user scripts):

function addGlobalStyle(css) {
    var head, style;
    head = document.getElementsByTagName('head')[0];
    if (!head) { return; }
    style = document.createElement('style');
    style.type = 'text/css';
    style.innerHTML = css;
    head.appendChild(style);
}

It’s a function you can call to add CSS rules to the page’s final CSS style.

Then, just call the function for all the styles you want to change using the CSS rules you found at step 3 before, in my case:

addGlobalStyle('.entryBody { max-width: 900px !important; }');
addGlobalStyle('#feedlyFrame { width: 1230px !important; }');
addGlobalStyle('#feedlyPage { width: 900px !important; }');
addGlobalStyle('.entryBody .content img { max-width: 850px !important; width: auto !important; height: auto !important; max-height: 600px !important;}');

All the !important markers are the dirty part: unless the page’s author used those herself (bad, bad author! :P) that tag ensures that your styles are being applied, no matter what. The great thing about !important (which is also the very bad thing) is that it makes styles overwrite definitions even if they’re specified within a style attribute in the element itself!
For example, in:

<div class="wide" style="width: 800px;">

the width value is always overridden by a CSS rule like this:

.wide {
  width: 900px !important;
}

which is both awesome and awful depending on the context 🙂
Feedly has some style definitions like that, and that’s why I needed the !important flags.

Then, save the script and test it!

You can do a lot more than just stuffing your filthy CSS code, of course. I found this great userscript that makes feedly look like google reader (isn’t that what we all want from an RSS reader?), and if you look at the code the author works around the style problem by adding event listeners for DOMNodeInserted, because feedly has a webpage that is built with DOM manipulation performed by javascript. Much more sophisticated 🙂

The lesson here is: search userscripts.org first, and only then create your hacks!