Simple webradio playback

I listen to web radio stations but I don’t want to use any player ui for that. All I want is:

  1. Select a station from a list of my favorites and listen to it
  2. Be able to stop current web-radio playback
  3. Never have more than one station playing at the same time

I do it like this:

  • For each radio station save a playlist file (*.pls, *.m3u or sometimes *.asx) in a folder called “radio” on my local machine. I download most of them from the shoutcast or icecast stream directories. I also add one special (empty) file called “none.pls” (which serves to turn off all radio).
  • Add a toolbar to the taskbar that lists the content of the radio folder, i.e. all the webradio playlist files as clickable items. In XFCE add a “Directory Menu” item to the panel.
  • Configure the default app for the playlist mime types mentioned above to be my bash script “radio.sh”. It kills any existing webradio playback and plays the selected playlist file. See below for how to configure mime-type association defaults.
  • Install mpv – the de-facto successor of the now dormant mplayer – to do the actual playback.

This is my little “radio.sh” script (requires the pkill and mpv commands):

#! /bin/bash
pkill -f "mpv --playlist" 
mpv -playlist "$@"

To set this script as the default handler for the most common playlist file types, put the following into ~/.local/share/applications/defaults.list:

[Default Applications]
audio/x-mpegurl=radio.sh.desktop
audio/x-scpls=radio.sh.desktop

Make sure you have a file “radio.sh.desktop” in ~/.local/share/applications or in /usr/local/share/applications with contents like this:

[Desktop Entry]
Exec=radio.sh %U
MimeType=audio/x-mpegurl;audio/x-scpls;video/x-ms-asf
Name=radio.sh
StartupNotify=false
Terminal=false
Type=Application

If I have to use M$ Windows then I do something similar using a taskbar toolbar for the radio folder and the VLC player, configured to run minimized as systray icon.

Bash script to remove CSS from epub

I have a Kobo Reader to read epub eBooks. It is a first generation Kobo and has a flaw: If the epub file contains a CSS stylesheet, the reader (that’s me) cannot adjust the font size via Kobo’s font selection.

Since epub is just zipped HTML with some metadata and conventions, I was able to fix the problem by removing all CSS files from the offending epub. I don’t want any fancy “style” or formatting for the books that I read anyway.

Here is the bash script that I use to automate the task (requires the zip/unzip commands):

file=$1

if [[ $file != *.epub ]]
then
  echo "Usage: $(basename $0) something.epub"
  exit 0
fi

folder=$(basename "$file" .epub)

mkdir "$folder"
unzip -d "$folder" "$file"

find "$folder" -name *.css -exec rm {} \;

cd "$folder" 
zip -r ../"$folder"_nocss.epub .
cd ..
rm -rf "$folder"

Set up sudo on Debian

Debian does not use sudo by default. I like sudo for admin tasks when being logged in as a regular user (mostly based on my experience with Ubuntu) for several reasons:

  • No risk of an open root shell
  • Logging of “who did it”
  • Selective access can be configured flexibly

What I don’t like in Ubuntu is that the sudo password is the regular user’s password and that the root account is actually disabled:

  • We lose one level of security (root password) and the regular user password is often not carefully chosen and maybe not kept secret enough (because maybe friends or family know it to do “regular user stuff” using your account.
  • In a “one admin person” system like your typical laptop or desktop there is no concern that the root password would have to be shared among several admins.

So for these reasons I usually configure a “one admin person” Debian system like this (replace REGULAR_USERNAME with your regular username that will be the admin):

su -
apt-get install sudo
adduser REGULAR_USERNAME sudo
visudo

In the visudo editor edit the “Defaults” line to use “targetpw”:

Defaults env_reset,targetpw

Then exit the root shell, log out as regular user and log in as regular user again (required to activate group membership).

Now your regular user should be able to do everything that root can do using sudo and the root password.

Fix udevd warnings after hplip installation

After installation of the latest hplip package (for HP printer support on GNU/Linux systems) you might see boot warnings like this:

udevd[281]: SYSFS{}= will be removed in a future udev version, please use ATTR{}= to match the event device, or ATTRS{}= to match a parent device, in /etc/udev/rules.d/86-hpmud-hp_laserjet_p1008.rules:6

To fix the problem I did this (on a Debian system):

sudo sed -i -e "s|SYSFS|ATTRS|g" -e "s|sysfs|attrs|g" /etc/udev/rules.d/*hpmud*.rules

Generate and display Maven Build timestamp in WAR

On all the pages of my webapp I want to see when the WAR was built (i.e. a build timestamp). Here is how I did it:

Add this to the pom.xml of your webapp module:

<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
    </resource>
  </resources>
</build> 

<properties>
  <mavenBuildTimestamp>${maven.build.timestamp}</mavenBuildTimestamp>
</properties>

Create a file src/main/resources/build.properties in  in your webapp module with the following content:

# Build Time Information
build.timestamp=${mavenBuildTimestamp}

The Maven build will replace the Maven property and the resulting file WEB-INF/classes/build.properties will look like this:

# Build Time Information
build.timestamp=20101016-0303

Now we just need a Spring PropertiesFactoryBean definition to make properties available at runtime:

<bean id="appProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="locations">
    <list>
      <value>classpath:build.properties</value>
    </list>
  </property>
</bean>

I used a simple Spring bean to make the timestamp easily available in Spring Web Flow / Spring Faces EL expressions:

@Component
public class ViewUtil {

  private Properties appProperties;

  /**
   * @param appProperties Global Application properties
   */
  @Resource
  public void setAppProperties(Properties appProperties) {
    this.appProperties = appProperties;
  }

  /**
   * @return The Build Timestamp as generated by Maven
   */
  public String getBuildTimestamp() {
    return appProperties.getProperty("build.timestamp", "UNKNOWN");
  }
}

The EL expression code in the JSF page is then something like this:

Build timestamp: #{viewUtil.buildTimestamp} 

And this is what the result looks like on the page:

Build Timestamp screenshot

If you want to be able to refer to properties directly by name in your Spring configuration you can define a Spring PropertyPlaceholderConfigurer:

<bean id="propertyConfigurer"
      class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
  <property name="properties" ref="appProperties" />
</bean>

APT pinning, Iceweasel upgrade, hide Facebook Ads

I am a pretty happy user of Debian 5 stable (“Lenny”). But some Lenny packages are a little too old for my taste.

For example, Iceweasel is version 3.0.6 in Lenny. But the latest Adblock Plus (1.1.1 and later) requires Firefox/Iceweasel 3.0.12 and Adblock Element Hiding Helper does not work correctly with Adblock Plus versions older than 1.1.1 (keeps ignoring the configured hiding patterns).

So I decided that I want Iceweasel 3.0.14 from Debian testing (“Squeeze”). I googled for APT Pinning and found this page

http://wiki.debian.org/AptPinning

The lower half of it explains a “conservative approach” to pinning that only installs testing packages when the user explicitly requests it. I created /etc/apt/preferences to look like this:

Package: *
Pin: release a=stable
Explanation: prefer stable
Pin-Priority: 900

Package: *
Pin: release o=Debian
Explanation: require approval
Pin-Priority: -10

Then I added the Debian testing repository to /etc/apt/sources.list, told apt to update itself and installed Iceweasel from testing:

apt-get update
apt-get install -t testing iceweasel

That worked nicely and upgraded only the Iceweasel package, nothing else.

Now I can use Adblock Plus with the Element Hiding Helper to get rid of the ads in Facebook by adding these Element Hiding Rules:

facebook.com##DIV.adcolumn
facebook.com##DIV.UIEMUASFrame.UIEMUASSLikeFrame
facebook.com##DIV.UIEMUASFrame

Yay! That was worth the effort …

Maven ‘skip tests’ & test-jar dependency errors

If you use test-jar dependencies in a multi-module Maven project (see my previous posting) you will run into a problem when you run Maven install with the maven.test.skip option turned on.

Problem

Maven looks for dependencies on test-jars even when maven.test.skip is turned on. This posting on the Maven issue tracker site perfectly summarizes the problem.

The maven.test.skip option (which is equivalent to the ‘Skip tests’ checkbox in IntelliJ’s Maven Runner options) prevents test code compilation, packaging and execution.

Hence no test-jars are built and that leads to the dependency error described above.

Solution

Disable the ‘Skip Tests’ checkbox in IntelliJ and INSTEAD add a property skipTests with value true.

This causes all test code to be built (and packaged as test-jars – when configured as described in my last posting) and only disables the execution of the tests.

Maven test execution options

maven.test.skip
Disables both running the tests and compiling the tests.

skipTests
Set this to true to skip running tests, but still compile them

Maven test-jar and test code reuse

In a multi module Maven project you might want to reuse test-related code (in src/test) across modules.

The recommended way is described here:
http://maven.apache.org/guides/mini/guide-attached-tests.html

You might want to exclude test classes from test-jar, to prevent that they run multiple times. Add this to your maven-jar-plugin definition (right after the <goals>..</goals> section) :

<configuration>
    <excludes>
        <exclude>**/*Test.class</exclude>
    </excludes>
</configuration>

This assumes that your test classes and only your test classes are named “…Test”.

More info on maven-jar-plugin configuration options for the test-jar goal:
http://maven.apache.org/plugins/maven-jar-plugin/test-jar-mojo.html

Virtualbox clipboard workaround

With Virtualbox OSE 1.5.2, host Kubuntu 7.10 and guest Win XP I have intermittent clipboard problems: Garbled text, often even from one Linux app to another.

I tried upgrading to VirtualBox 1.5.4 non-free but had network problems with it.

Finally I came up with the following workaround. The idea is to write/read the clipboard using a temporary shared file. Prerequisites:

  • Install xclip in Kubuntu.
  • Put the cat, pclip and gclip commands in the PATH of the Windows system.
  • Set up a Samba share that both guest and host can read and write to.

In my setup the share is /share in the guest and mounted as network drive S: in the guest. The temporary file will be in /share/clipboard/.

Create an application shortcut in Kubuntu with the Application command

xclip -o > /share/clipboard/clip.txt

and drag it on the taskbar so that you can execute it with one click. To avoid annoying startup notifications disable them in the “Advanced Options” in the “Application” tab of the shortcut. Now you should be able to copy the content of the X clipboard to the temporary file with one click.

In the guest system (Windows) you do the same thing in reverse but with a keyboard shortcut: Put a file clip-in.bat into a safe location (where you won’t accidentally delete it) with the following one line of code:

cat S:\clipboard\clip.txt | gclip

Create a desktop shortcut pointing to clip-in.bat and define a keybard shortcut for it (under right-click, Properties..), e.g. ALT-CTRL-C.

Now you should be able to mark and paste from the host to the guest system in the following way:

  • Mark some text in the host (Kubuntu) system
  • Click the shortcut in the KDE taskbar
  • In the host system press CTR-ALT-C and then CTRL-V (to paste)