Monday, August 20, 2007

Windows USB thumb drive scripts

This batch file adds right click context menu for all files. So, you can drag and drop gvim.exe to the batch file and have gvim context menu for all files. If it doesn't work, it'll at least create addcontext.reg file to the folder the executable is located. Go to the folder and double click addcontext.reg

@echo off
setlocal
set app_name=%~n1
set app_abs=%~f1
set app=%app_abs:\=\\%
set command=@="%app% \"%%1\""
set workingdir="%~dp0"
set regname=%workingdir%\addcontext.reg
echo Windows Registry Editor Version 5.00 > %regname%
echo. >> %regname%
echo [HKEY_CURRENT_USER\Software\Classes\*\shell] >> %regname%
echo. >> %regname%
echo [HKEY_CURRENT_USER\Software\Classes\*\shell\%app_name%] >> %regname%
echo. >> %regname%
echo [HKEY_CURRENT_USER\Software\Classes\*\shell\%app_name%\command] >> %regname%
echo %command% >> %regname%
regedit.exe /s %regname%
echo %app_name% context menu installed
endlocal
pause

Run this reg file to remove the context menu:

Windows Registry Editor Version 5.00

[-HKEY_CURRENT_USER\Software\Classes\*\shell]

This reg file adds opencmd context menu to folders that opens cmd.exe on that folder:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\Folder\shell]

[HKEY_CURRENT_USER\Software\Classes\Folder\shell\opencmd]

[HKEY_CURRENT_USER\Software\Classes\Folder\shell\opencmd\command]
@="Cmd.exe /k pushd %L"

Run this reg file to remove opencmd context menu:

Windows Registry Editor Version 5.00

[-HKEY_CURRENT_USER\Software\Classes\Folder\shell]

gtk2hs compiled!!

I tried to install gtk2hs for a couple of days. And finally, it succeeds! Somehow, I had to turn off compiler optimization (-O0). Here is PKGBUILD for Archlinux:

pkgname=gtk2hs
pkgver=0.9.12
pkgrel=1
pkgdesc="A GUI Library for Haskell based on Gtk"
url="http://haskell.org/gtk2hs/"
license=('GPL')
depends=('ghc' 'gtk2' 'libglade' 'librsvg' 'gtkglext' 'cairo' 'gtksourceview')
arch=('i686')
source=($pkgname-$pkgver.tar.gz)
install=gtk2hs.install
md5sums=('32752a42c225f55b0280151f8e19a3ed')
build() {
    cd $startdir/src/$pkgname-$pkgver
    ./configure --prefix=/usr --without-pkgreg --disable-split-objs --with-hcflags=-O0
    make || return 1
    make DESTDIR=$startdir/pkg install
}

This is gtk2hs.install file. Without --force, it fails somehow.

post_install() {
    for pkg in /usr/lib/gtk2hs/*.package.conf; do
        ghc-pkg register "$pkg" -g --force
    done
}

post_upgrade() {
    for pkg in /usr/lib/gtk2hs/*.package.conf; do
        #basename $pkg .package.conf
        tmp="${pkg##*/}"
        ghc-pkg unregister "${tmp%%.*}" && ghc-pkg register "$pkg" -g --force
    done
}

pre_remove() {
    for pkg in /usr/lib/gtk2hs/*.package.conf; do
        tmp="${pkg##*/}"
        ghc-pkg unregister "${tmp%%.*}" -g #2>/dev/null
    done
    rm /usr/lib/gtk2hs/*.o
}

op=$1
shift
$op $*

Now, haskell with gui goodness.

Friday, August 17, 2007

pymv

pymv reads file names listed in an xml file and moves them to a directory. It can also move files not listed in the xml file to the directory.

"""moves files listed in xml file to dst directory."""

import sys, os, shutil, optparse, re
from xml.dom import minidom

def domv(src, dst, simulate=True):
    "mv src dst"
    if (not simulate) and os.path.exists(src):
        try:
            shutil.move(src,dst)
        except IOError, err:
            print err.message
        except OSError, err:
            print err.message

def mkre(s):
    """*.mp3 => ^.*\.mp3$"""
    return '^%s$' % re.escape(s).replace('\*', '.*')

def get_nodes(xmldoc, base, tag, attrib, value, no_attrib, from_attrib):
    """retrieves file names from nodes that looks like:
    <tag attrib="value">filename.txt</tag> => base/filename.txt
    when no_attrib=True, attrib="value" is not tested."""
    elements = xmldoc.getElementsByTagName(tag)

    if (attrib is None) or (value is None): #attribute not given.
        no_attrib = True #don't filter using attribute
        from_attrib = False #don't get filename from attribute

    if no_attrib: #don't want to filter using attribute
        attrib_test = lambda x: True
    else: #want to filter using attribute
        print mkre(value)
        attrib_test = lambda x: re.match(mkre(value), str(x))

    if from_attrib: #get filenames from attrib
        result = []
        for x in elements:
            attribute = x.getAttribute(attrib)
            if attrib_test(attribute):
                result.append(os.path.join(base, attribute))
        return result

    #get filenames from node.data
    return [os.path.join(base, x.firstChild.data)
            for x in elements
            if attrib_test(x.getAttribute(attrib)) and x.hasChildNodes()]

def main(argv=None):
    if argv is None:
        argv = sys.argv

    cliparser = optparse.OptionParser(
            usage='Usage: %prog [options] xml destdir')
    cliparser.add_option('-f', '--flip'
            , action="store_true"
            , help="moves files not listed in xml [default: %default]")
    cliparser.add_option('-b', '--base'
            , help="location of files listed in xml [default: where xml is located]")
    cliparser.add_option('-t', '--tag'
            , help="tag name to be searched for file names [default: %default]")
    cliparser.add_option('-a', '--attrib'
            , help="attributes to match [default: %default]")
    cliparser.add_option('-v', '--attrib-val'
            , help="attribute value to match. * matches everything. *.mp3 matches attrib=\"anything.mp3\" [default: %default]")
    cliparser.add_option('-n', '--no-attrib'
            , action="store_true"
            , help="don't test for attrib when selecting xml node [default: %default]")
    cliparser.add_option('-s', '--simulate'
            , action="store_true"
            , help="simulate. don't actually move files [default: %default]")
    cliparser.add_option('--from-attrib'
            , action="store_true"
            , help="get filename from attribute, not from node.data [default: %default]")

    cliparser.set_defaults(flip=False
            , tag="file"
            , attrib=None
            , attrib_val=None
            , no_attrib=False
            , simulate=False
            , from_attrib=False)

    (options, args) = cliparser.parse_args()

    arg_len = len(args)

    if arg_len < 2:
        cliparser.error("should pass xml, destdir")

    xmlf = os.path.abspath(args[0])
    dst = os.path.abspath(args[1])
    if options.base:
        base = os.path.abspath(options.base)
    else:
        #set to where xmlf is located
        base = os.path.dirname(xmlf)
    tag = options.tag
    attrib = options.attrib
    value = options.attrib_val
    no_attrib = options.no_attrib
    simulate = options.simulate
    from_attrib = options.from_attrib

    xmldoc = minidom.parse(xmlf)

    print 'Searching nodes: <%s %s="%s">' % (tag, attrib, value)
    filenames = get_nodes(xmldoc, base, tag, attrib, value
            , no_attrib, from_attrib)

    if simulate:
        for x in filenames:
            print x

    if not os.path.exists(dst):
        print "%(dst)s doesn't exist. Creating %(dst)s" % {'dst':dst}
        if not simulate:
            os.mkdir(dst)
    elif not os.path.isdir(dst): #dst exists but not directory.
        print """%(dst)s exists. And it's not a directory.
        Make sure %(dst)s is a directory.""" % {'dst':dst}
        sys.exit(1)

    if options.flip:
        for x in os.listdir(base):
            src = os.path.join(base, x)
            if os.path.isfile(src)\
                    and (src not in filenames)\
                    and (not src == xmlf):
                print "moving %(x)s to %(dst)s..." % {'x':x, 'dst':dst}
                domv(src, dst, simulate)
    else:
        for x in filenames:
            print "moving %(x)s to %(dst)s..." % {'x':x, 'dst':dst}
            domv(x, dst, simulate)

if __name__ == "__main__":
    main()