Archive

Author Archive

Uncompressing UNIX *.Z files

December 6th, 2009 8 comments

I searched online for a .NET library that can be used to decompress *.Z files (compressed by the UNIX compress utility) but was unable to find anything non-commercial. I found however some code in Java that looked promising, so I ported it to C#. I integrated the resulting code with the SharpZipLib library, but until that gets officially integrated and released, I decided to release a stand-alone version here.

The code is contained in a single file (download LzwInputStream.cs) and is pretty straight-forward to use. The following example shows how to uncompress a *.Z file using c-sharp.

using System;
using System.IO;

using Ebixio.LZW;

class MainClass
{
    public static void Main(string[] args)
    {
        byte[] buffer = new byte[4096];
        string outFile = Path.GetFileNameWithoutExtension(args[0]);

        using (Stream inStream = new LzwInputStream(File.OpenRead(args[0])))
        using (FileStream outStream = File.Create(outFile)) {
            int read;
            while ((read = inStream.Read(buffer, 0, buffer.Length)) > 0) {
                outStream.Write(buffer, 0, read);
            }
        }
    }
}

Git file transition diagram

November 5th, 2009 No comments

Here’s a Git cheat sheet on how to move content between the working directory, the staged area (the .git/index file) and the committed Git repository. It shows what happens to the file F (or more correctly, to its content) in response to various git commands and how to undo/revert an edit, or a git add.

F’ represents the first modification to F, and F” the second modification to F.

File transitions in Git

File transitions in Git

Categories: Uncategorized Tags:

Script to show id3v2 frames present or absent in a file

October 29th, 2009 No comments

This is a very simple script. See the usage at the top of the script starting on line 28.

#!/bin/bash

# Author: Gabriel Burca (gburca dash mp3 at ebixio dot com)
# Version: 1.0
#
# Copyright (C) 2006-2009  Gabriel Burca (gburca dash mp3 at ebixio dot com)
#
# 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 2
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


set -o nounset
set -o errexit

function usage () {
    cat << EOF
Checks for particular id3v2 frames in a set of files.
Usage:
    $0 <option> <FRAME> files...

Options:
    -m | --missing  Show files that are missing the frame
    -h | --has      Show files that have the frame
    -s | --show     Show the contents of the frame
    -a | --all      Show all the frames

For example, to find mp3's with no album art:
    $0 -m APIC *.mp3

Some sample frames:
    APIC    - Cover art
    TIT2    - Song name
    TPE1    - Artist
    TALB    - Album
    TCON    - Genre
EOF
}

function FilesWithoutFrame() {
    FRAME=$1
    shift

    for file in $@ ; do
        id3v2 -R "$file" | egrep "^$FRAME " 2>&1 > /dev/null
        if [ $? -gt 0 ]; then
            # $file is missing $FRAME
            echo $file
        fi
    done
}

function FilesWithFrame() {
    FRAME=$1
    shift

    for file in $@ ; do
        id3v2 -R "$file" | egrep "^$FRAME " 2>&1> /dev/null
        if [ $? -eq 0 ]; then
            # $file has $FRAME
            echo $file
        fi
    done
}

function ShowFrameContents() {
    FRAME=$1
    shift

    for file in $@ ; do
        id3v2 -R "$file" | egrep "^$FRAME "
    done
}

function ShowAll() {
    for file in $@; do
        echo
        echo
        id3v2 -R "$file"
    done
}


################################################################################
# main()
################################################################################

if [ $# -lt 2 ]; then
    usage
    exit 1
fi

IFS_orig=$IFS
IFS='
'

case $1 in
    -m | --missing)
        shift
        FilesWithoutFrame $@
        ;;
    -h | --has)
        shift
        FilesWithFrame $@
        ;;
    -s | --show)
        shift
        ShowFrameContents $@
        ;;
    -a | --all)
        shift
        ShowAll $@
        ;;
    *)
        usage
        exit 1
        ;;
esac

IFS=$IFS_orig
Categories: Uncategorized Tags: , , , ,

Convert flac and wav files to mp3

October 22nd, 2009 No comments

In case it might be useful to others, here’s a script that can be used to convert a bunch of *.wav files to *.flac and *.flac files to *.mp3. The script will first first convert all *.wav files (if any) to *.flac, then it will convert all *.flac files to *.mp3. See the usage instructions starting on line 31 below for more details.

I called the script

Watch Full Movie Online Streaming Online and Download

flac2mp3dir.sh

#!/bin/bash

# Author: Gabriel Burca (gburca dash flac2mp3dir at ebixio dot com)
# Version: 1.0
#
# Copyright (C) 2006-2009  Gabriel Burca (gburca dash flac2mp3dir at ebixio dot com)
#
# 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 2
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


set -o nounset
set -o errexit

function usage () {
    cat << EOF
Usage:
$0 source/dir dest/dir

All wav/flac files in source/dir and its subdirectories will be converted to
mp3 and placed in dest/dir while maintaining the directory structures. ID3
tags will also be copied from flac to mp3 files.

Existing files (mp3 or flac) will not be overwritten.
Source and destination directories can be the same.

EOF
}

function absname () {
        # Returns the absolute filename of a given file or directory.
        if [ -d "$1" ] ; then   # Only a directory name.
                dir="$1"
                #unset file
                file=""
        elif [ -f "$1" ] ; then # Strip off and save the filename.
                dir=$(dirname "$1")
                file="/"$(basename "$1")
        else
                # The file did not exist.
                # Return null string as error.
                echo
                return 1
        fi
 
        # Change to the directory and display the absolute pathname.
        cd "$dir"  > /dev/null
        echo "${PWD}${file}"
}

function flac2mp3 () {
        INF="$1"
        OUTF=`echo "$INF" | sed 's/\.flac$/.mp3/'`
        PWD=`pwd`
        SUBDIR=${PWD:$SRCDIRLEN}
        #SUBDIR=${PWD#$SRCDIR}

        INF="$PWD/$INF"
        OUTF="$DESTDIR$SUBDIR/$OUTF"
        #echo "$INF ... $PWD $SRCDIRLEN $SUBDIR $OUTF"

        if [ -e "$OUTF" ] ; then
                if [ "$OUTF" -ot "$INF" ] ; then
                        echo "*** Re-converting old file: $OUTF"
                        # rm -f "$OUTF"
                else
                        echo "*** Skip flac2mp3! Output file already exists: $OUTF"
                        return
                fi
        fi

        if [ ! -e "$DESTDIR$SUBDIR" ] ; then
                mkdir -p "$DESTDIR$SUBDIR"
        fi

        # Convert flac to mp3
        echo "${INDENT}flac2mp3 Converting $INF => $OUTF"
        #touch "$OUTF"
        flac -c -d "$INF" | lame --preset standard --replaygain-accurate - "$OUTF"

        # Copy tags to new file
        id3 -D "$INF" -1 -2 "$OUTF"

        # Copy non-flac/non-wav (folder.jpg, etc...) files to dest/dir
        if [[ ! -e "$DESTDIR$SUBDIR/folder.jpg" && -e "folder.jpg" ]] ; then
                cp folder.jpg "$DESTDIR$SUBDIR"
        fi
}

function wav2mp3 () {
        INF="$1"
        OUTF=`echo "$INF" | sed 's/\.wav$/.flac/'`

        if [ -e "$OUTF" ] ; then
                echo "*** Skip wav2mp3! Output file already exists: $OUTF"
                return
        fi

        echo "${INDENT}wav2mp3 Converting $INF => $OUTF"
        #touch "$OUTF"
        flac -V -o "$OUTF" "$INF"
        flac2mp3 "$OUTF"
}

function traveldir ()
{
        dir="$1"

        pushd "$dir" > /dev/null
        echo "Entering: `pwd`"

        for a in *
        do
                if test -d "$a" ; then
                        traveldir "$a"
                else
                        if [[ `expr match "$a" '.*\\.flac$'` > 0 ]] ; then
                                flac2mp3 "$a"
                        elif [[ `expr match "$a" '.*\\.wav$'` > 0 ]] ; then
                                wav2mp3 "$a"
                        else
                                echo "${INDENT}Skipping: $a"
                        fi
                fi
        done
        popd > /dev/null
}

################################################################################
# main()
################################################################################

if [[ $# < "2" ]] ; then
        usage
        exit 1
fi

SRCDIR="$1"
DESTDIR="$2"

if [[ ! -e "$DESTDIR" ]] ; then
        mkdir -p "$DESTDIR"
fi

if [[ ! -e "$SRCDIR" ]] ; then
        echo "$SRCDIR does not exist!"
        exit 2
fi

# Get absolute directories
SRCDIR=$(absname "$SRCDIR")
DESTDIR=`absname "$DESTDIR"`

SRCDIRLEN=`expr length "$SRCDIR"`
INDENT="    "

pushd . > /dev/null
traveldir "$SRCDIR"
popd > /dev/null
Categories: Uncategorized Tags: , , , , , ,

Git filter-branch incantations

October 15th, 2009 No comments

Here’s an example of how to use the git filter-branch command with the –env-filter option:

git checkout mybranch
git filter-branch --env-filter "export \
    GIT_AUTHOR_NAME='Your Name' \
    GIT_AUTHOR_EMAIL='email@example.com' \
    GIT_COMMITTER_NAME='Your Name' \
    GIT_COMMITTER_EMAIL='email@example.com'" \
    HEAD~4..HEAD

Notice that on line 7, the first reference (HEAD~4 in this example) needs to be the parent of the first (oldest) commit you want to change.

Verify that your changes are good by comparing the rewritten commits with the original/refs/heads/mybranch reference that filter-branch saves. If all is good, delete the original reference:

git update-ref -d refs/original/refs/heads/mybranch

In one of my old subversion projects I did some branch merges before SVN started tracking merges with meta-data. When the project was converted to GIT, what I ended up with were some branches that seemed to lead to nowhere (they looked like they were abandoned and never merged back into the trunk). Git had no way of knowing at what point the side-branches became integrated into the trunk because in early versions of SVN there was no meta-data to track merges. I have no plans to go back to SVN, so I decided to fix this “cosmetic” issue.

Git filter-branch to the rescue. The –parent-filter allows you to rewrite the parents of a commit. All I need to do is find the trunk commit that the branches were merged into and make the side-branch tip a second parent of that commit.

git filter-branch --parent-filter \
    'test $GIT_COMMIT = 9d2104a09307b44a3640ae368916edd80e966290 && \
    echo "-p a3f23400f469a327310513e9a20a0d717e7bc04f \
          -p 512e8f229bba27bbec1df49607e7717db760edec" \
    || cat' \
    --tag-name-filter 'cat' \
    a3f23400f469a327310513e9a20a0d717e7bc04f..master

Explanation: Line 2 contains the SHA1 (9d210…) of the SVN revision that is missing a parent. This is the revision into which the dangling head (512e8…) was actually merged in SVN, but which git does not show as containing 512e8.

Line 3 has the first parent (a3f23…) which was there before the filter-branch. We need to retain this parent. Line 4 has the SHA1 (512e8…) of the missing parent. Both of these will become parents of 9d210.

The cat is there because we want to keep all commits that don’t match 9d210… unchanged.

Lastly, line 6 is there to retain the existing tags, and line 7 covers the range we want to modify (notice that this extends from the parent of 9d210 to the tip of the master branch).

Categories: Uncategorized Tags: , ,