Wednesday 26 December 2012

Deleting Duplicate Files in Backups

rsync-backup (and other variants) can reduce backup size by referring to previous backups; although this can make the backup process slower and requires some fore-thought.

This script allows post-backup size reduction by detecting duplicate files in backups and making them share the same hardlink target, saving disk space.

We keep a placeholder link in MD5 folder. Each file whose MD5 file already exists in the MD5 folder is forced as a link to that MD5 file. Otherwise we link the file to create that MD5 file.

mkdir -p MD5
find . -path ./MD5 -prune -o -type f | xargs md5sum  | while read md5 file
do if test -f "MD5/$md5"
   then ln -f "MD5/$md5" "$file"
   else ln "$file" "MD5/$md5"
   echo "$md5 $file"

Because we keep an MD5 directory we don't need the md5 list to be sorted and we can re-run the script later on a smaller disk subset without needing to refer to the full MD5 list.

We can also easily examine the MD5 directory to see how many copies of a specific file exist and how much disk space is saved.

Any files in MD5 directory with only 1 link have been deleted from the normal file system tree and could also be deleted... but serve as a backup-backup!

Friday 7 December 2012

Media Buttons on Mint 14 Nadia

Sadly keyboard multi-media control buttons still have no effect on Mint 14 when logged in using the Gnome2 fork Mate desktop.

Gladly, Matteo Italia has written a short python script to convert the DBUS events into MPRIS2 events.

Start the script on login and media keys work! Thanks Matteo

#!/usr/bin/env python

Created on 30.05.2012

@author: Matteo Italia <>

import dbus
import dbus.mainloop.glib
import gobject

app_name = 'mmkeys-mate2mpris2'

MediaKeysObjName = 'org.mate.SettingsDaemon'
MediaKeysObjectPath = '/org/mate/SettingsDaemon/MediaKeys'
MediaKeysInterface = 'org.mate.SettingsDaemon.MediaKeys'

MPRIS2Prefix = 'org.mpris.MediaPlayer2'

ActionMappings = {
        'Play': 'PlayPause',
        'Pause': 'Pause',
        'Stop': 'Stop',
        'Next': 'Next',
        'Previous': 'Previous'}

def onMediaKeyPress(app_name, action):
    sb = dbus.SessionBus()
    # Get the compatible players
    players = [n for n in sb.list_names() if n.startswith(MPRIS2Prefix + ".") ]

    # Send them the command
    for n in players:
        # TODO: it doesn't make sense to perform the action on *all* the players!
        # find a sensible criterion to choose the "best one"
        sb.get_object(n, '/org/mpris/MediaPlayer2').__getattr__(ActionMappings[action])()

if __name__ == '__main__':

    # DBUS boilerplate
    sb = dbus.SessionBus()

    # Get the media keys notificator object
    mediaKeysObj = sb.get_object(MediaKeysObjName, MediaKeysObjectPath)

    # Register to receive media keys notifications
    mediaKeysObj.GrabMediaPlayerKeys(app_name, 0, dbus_interface=MediaKeysInterface)
    mediaKeysObj.connect_to_signal('MediaPlayerKeyPressed', onMediaKeyPress)

    # Start the main loop
    mainLoop = gobject.MainLoop()