Thursday 24 September 2009

Motherboard for Show & Tell for 2nd class.

Kate brought a motherboard in to school for show & tell today. :) She was able to give an interesting description of CPU, Memory and Clock. Kids at home were all practicing removing & replacing CPU and memory - tough for little fingers - jumpers have been moved all-over-the place.

About the CPU she said something like it's where everything goes in and gets collected and where everything happens like making the pictures for the screen.

Good use for geek-Dad's museums of old parts.
It's a board where the battery was soldered onto a flash chip for the bios.
A pin broke off when trying to replace the battery.
686 CPU, Very pretty blue heat sink and fan.

Monday 21 September 2009

book - boys adventure - Max Gordon

http://www.puffin.co.uk/static/cs/uk/15/minisites/dangerzone/max_gordon.php
http://en.wikipedia.org/wiki/David_Gilman

title: The Devil's Breath
author: David Gilman
a Max Gordon book

Finished this one last night. Another one borrowed from Daire's reading pile. Good adventure story. Max's Dad is an adventurer/eco-spy type person. Max hares off (adventure/boarding school in the moors) to London and then Namibia to rescue his Dad.

I like that the geography and people and actions are very engaging. Where geography mostly = Africa, animals, the bush. Where actions = lots of physical exertion, climbing, flying airplane.

Stop reading now! I have to be slightly picky about the technology which was done better than in many books/films. The computer details were handwaved over and passed off to his friend computer-genius Sayid a bit. Encrypted text messages. Mmm. It's difficult, if you avoid it you're missing something, if you simplify it you'll be criticised for that and if you go into it properly you'd bore 99.99902934% of people but thrill 0.0005% of them. Mmm.



Hmm. That Amazon link/html not working?
I'm experimenting with Amazon affiliate links.
How about this:

Wednesday 16 September 2009

HowTo Import Livejournal blog to Blogger

Get google-blog-converters python scripts.
http://code.google.com/p/google-blog-converters-appengine/downloads/list
I got google-blog-converters-1.0-r64.tar.gz

I already had python 2.6.x and I seemed to also have google's gdata python libs already installed. Get gdata following instructions here: http://code.google.com/p/gdata-python-client/ if you don't already have it, unpack and sudo ./setup.py install.

Unpack the google-blog-convertors package and:
bin/livejournal2blogger.sh -u -p |tee my_livejournal.xml

Remove the nasty Ctrl-D chars from that file! (emacs replace-string Ctrl-QCtrl-D)

Blogger Dashboard -> Settings -> Import

More on GoogleData and Atom and ..
http://code.google.com/apis/gdata/

Friday 11 September 2009

a tcl launcher for XQual XStudio ...

It was trivial to modify the XQual XStudio launcher for perl to work for tcl (ActiveTcl).
It is working for very simple tcl scripts with ActiveTcl 8.5 (and with modification with 8.4).

Change the perl CLauncherImpl.java thusly:
s/perl/tcl/gi; s/\.pl/\.tcl/g;
Tcl interpreter: C:/Tcl/bin/tclsh85.exe

It implements the same test interface as XStudio perl (and other):
* Test generates log.txt with lines including [Success] or [Failure] or [Log].
* Test is deemed complete when a file test_completed.txt is created.

Note for XQual XStudio:
* tools seems very nice to use, developer good - closed source though ...
* source code for test launchers is provided in XAgent and XStudio dir trees.
* there doesn't seem to be a Developers Guide though it is referred to (there are javadocs)
* a launcher has 4 files (e.g. for tcl) tcl.jar and tcl.xml in launchers/, tcl/CLauncherImpl.java and buildTclLauncher.bat in src/*/ and build/

I've been evaluating using XQual XStudio as a test invoking tool. As opposed to Salome_tmf.
http://www.xqual.com/
http://xqual.freeforums.org/evaluating-test-tools-xqual-xstudio-salome-tmf-t349.html


Files here:
http://www.dspsrv.com/~jamesc/torture/work/tool_xqual_xstudio/

/*
+----------------------------------------------------------------------+
| Class: CLauncher |
| |
| Developer: Eric Gavaldo (egavaldo@xqual.com) |
| Jumbo |
| James Coleman (jamesc@dspsrv.com) |
| |
+----------------------------------------------------------------------+
*/

/*
This file was created by changing the perl CLauncherImpl.java
s/perl/tcl/gi; s/\.pl/\.tcl/g;
It has been tested with ActiveTcl, tcl interpreter: C:/Tcl/bin/tclsh85.exe

It implements the same test interface as XStudio perl (and other).
Test generates log.txt with lines including [Success] or [Failure]
or [Log]. Test is deemed complete when a file test_completed.txt is created.
*/

package com.xqual.xlauncher.tcl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Vector;

import com.xqual.xagent.launcher.CExecutionStep;
import com.xqual.xagent.launcher.CLauncher;
import com.xqual.xagent.launcher.CParamParsingException;
import com.xqual.xagent.launcher.CReturnStatus;
import com.xqual.xagent.launcher.runner.CRunner;
import com.xqual.xagent.launcher.runner.IRunner;
import com.xqual.xcommon.CAttribute;
import com.xqual.xcommon.IConstantsResults;
import com.xqual.xlauncher.CTimeoutListener;

/**
* The CLauncherImpl implementation of ILauncher for Tcl.
* @author egavaldo & jumbo & jamesc
*/
public class CLauncherImpl extends CLauncher implements IConstantsResults {

// +==============================================================+
// | Attributes |
// +==============================================================+

static final String TRACE_HEADER = "{tcl } ";

// parameters impacting executing at run time set by the test operator
private String testRootPath;
private int timeout = 600;
private String tclInstallPath;
private File tclInterpreter;

private File workingDir;

private static final String TCL_INTERPRETER_EXE = "tclsh85.exe";

// +==============================================================+
// | Constructors |
// +==============================================================+

public CLauncherImpl() {
super(TRACE_HEADER);
}

// +==============================================================+
// | Methods |
// +==============================================================+

public CReturnStatus initialize(int sutId, String sutName, String sutVersion) {
setSutDetails(sutId, sutName, sutVersion);

// check the configuration sent by the manager
printConfiguration();

Vector executionSteps = new Vector();
try {
// retrieve the parameters we need
testRootPath = getStringParamValue("General", "Test root path");
timeout = getIntegerParamValue("General", "Asynchronous timeout (in seconds)");

tclInstallPath = getStringParamValue("Tcl", "Tcl install path");
tclInterpreter = new File(tclInstallPath + "\\" + TCL_INTERPRETER_EXE);
} catch (CParamParsingException e) {
traceln(LOG_PRIORITY_SEVERE, "parsing error during initialization");
executionSteps.add(new CExecutionStep(RESULT_FAILURE, "Exception during initialize: " + e.getMessage()));
return new CReturnStatus(RESULT_FAILURE, executionSteps);
}
return new CReturnStatus(RESULT_SUCCESS, executionSteps);
}

public CReturnStatus preRun(int testId, String testPath, String testName, Vector attributes) {
traceln(LOG_PRIORITY_INFO, "preRun testId=" + testId + " testPath=" + testPath + ":" + testName + "...");
Vector executionSteps = new Vector();
return new CReturnStatus(RESULT_SUCCESS, executionSteps);
}

public CReturnStatus run(int testId, String testPath, String testName, int testcaseIndex) {
traceln(LOG_PRIORITY_INFO, "run testId=" + testId + " testPath=" + testRootPath + "/" + testPath + "/" + testName + " testcaseIndex=" + testcaseIndex + "...");
Vector executionSteps = new Vector();

String scriptParentFolderPath = testRootPath + "/" + testPath + "/";
workingDir = new File(scriptParentFolderPath);

// +------------------------------------+
// | Interpret the script
// +------------------------------------+
CRunner tclRunner = new CRunner("[" + testId + "] "+ testPath + ":" + testName + "." + testcaseIndex,
tclInterpreter.toString() + " " + testRootPath + "/" + testPath + "/" + testName + ".tcl " +
"/debug " +
"/testcaseIndex=" + testcaseIndex,
workingDir);
short result = tclRunner.requestAction(IRunner.START_PROCESS, IRunner.DO_NOT_WAIT_END_OF_EXECUTION);
if (result == RESULT_FAILURE) {
executionSteps.add(new CExecutionStep(RESULT_FAILURE, "script interpretation failed"));
return new CReturnStatus(RESULT_FAILURE, executionSteps);
}

// to check if the execution completed correctly, we need to check if the "test_completed.txt" has been created
short resultTimeout = CTimeoutListener.waitForFile(new File(workingDir + "/test_completed.txt"), timeout);
if (resultTimeout != RESULT_SUCCESS) {
executionSteps.add(new CExecutionStep(RESULT_SUCCESS, "timeout of " + timeout + " seconds to execute the test case expired"));
return new CReturnStatus(RESULT_FAILURE, executionSteps);
}

return parseResultFile(executionSteps);
}

public CReturnStatus postRun(int testId, String testPath, String testName) {
traceln(LOG_PRIORITY_INFO, "postRun testId=" + testId + " testPath=" + testPath + ":" + testName + "...");
Vector executionSteps = new Vector();
executionSteps.add(new CExecutionStep(RESULT_SUCCESS, "postRun: succeeded"));
return new CReturnStatus(RESULT_SUCCESS, null);
}

public CReturnStatus terminate() {
Vector executionSteps = new Vector();
executionSteps.add(new CExecutionStep(RESULT_SUCCESS, "Terminate"));
return new CReturnStatus(RESULT_SUCCESS, executionSteps);
}

// +--------------------------+
// ¦ Utilities ¦
// +--------------------------+

private CReturnStatus parseResultFile(Vector executionSteps) {
// parse the result file to get the result and the execution steps
File resultFile = new File(workingDir + "/log.txt");
if (!resultFile.exists()) {
traceln(LOG_PRIORITY_SEVERE, "Result file not found!");
executionSteps.add(new CExecutionStep(RESULT_FAILURE, "run: result file not found!"));
return new CReturnStatus(RESULT_FAILURE, executionSteps);
} else {
executionSteps.add(new CExecutionStep(RESULT_SUCCESS, "run: result file found"));
}

String line, message;
boolean errorDetected = false;

try {
FileInputStream fileInputStream = new FileInputStream(resultFile);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));

while ((line = bufferedReader.readLine()) != null) {
line = line.trim();
System.out.println(">" + line);
if (line.indexOf("[Success]")>=0) {
message = line.substring(10, line.length()); // [Success] length = 9
executionSteps.add(new CExecutionStep(RESULT_SUCCESS, message));

} else if (line.indexOf("[Failure]")>=0) {
message = line.substring(10, line.length());
executionSteps.add(new CExecutionStep(RESULT_FAILURE, message));
errorDetected = true;

} else if (line.indexOf("[Log]")>=0) {
message = line.substring(6, line.length());
executionSteps.add(new CExecutionStep(RESULT_UNKNOWN, message));

} else {
//traceln(LOG_PRIORITY_SEVERE, "unknown tag!");
}
}

} catch (Exception e) {
traceln(LOG_PRIORITY_SEVERE, "exception whle parsing the result file: " + e);
executionSteps.add(new CExecutionStep(RESULT_FAILURE, "Exception whle parsing the result file: " + e));
errorDetected = true;
}

if (errorDetected) {
return new CReturnStatus(RESULT_FAILURE, executionSteps);
} else {
return new CReturnStatus(RESULT_SUCCESS, executionSteps);
}
}
}

Wednesday 2 September 2009

automatic sync mobile photos, map traces

Let's all sing the "let's automate" song!

Incidentally started new job with Intune http://www.intunenetworks.com Monday.
Finished with Sun http://www.sun.com Friday!
Kids all started back to school Tue.

script created just now: bt-sync-mobile.sh

TODO: cron job to daily sync phone


#!/bin/bash

#INVOCATION:
#$ bt-sync-mobile.sh [device [dir]]
#$ bt-sync-mobile.sh Pooky 'C:\Data\Images\' 2>&1 |tee .btsync/bt_sync_images.log
#Stuff is synched to ~/.btsync/`echo $dir |sed 's/[\/ \\"]/_/g'`
#wami*.gpx and *.jpg files are cleared off device if synced successfully
#
#REQUIREMENTS:
#linux with bluetooth hardware
#various bluetooth linux utils, these ubuntu packages:
#bluez bluez-utils(?) obexftp openobex-apps
#
# some of these come by default, and some are not needed, but this is on the system the script was tested on
#$ dpkg -l |egrep "bluez|hci|obex" |sed 's/ */ /g'
#ii bluez 4.32-0ubuntu4.1 Bluetooth tools and daemons
#ii bluez-alsa 4.32-0ubuntu4.1 Bluetooth audio support
#ii bluez-cups 4.32-0ubuntu4.1 Bluetooth printer driver for CUPS
#ii bluez-gnome 1.8-0ubuntu5 Bluetooth utilities for GNOME
#ii bluez-gstreamer 4.32-0ubuntu4.1 Bluetooth gstreamer support
#ii bluez-utils 4.32-0ubuntu4.1 Transitional package
#ii gnome-vfs-obexftp 0.4-1build1 GNOME VFS module for OBEX FTP
#ii libopenobex1 1.5-1 OBEX protocol library
#ii libopenobex1-dev 1.5-1 OBEX protocol library - development files
#ii obex-data-server 0.4.4-0ubuntu1 D-Bus service for OBEX client and server sid
#ii obexftp 0.19-7ubuntu2 file transfer utility for devices that use t
#ii openobex-apps 1.5-1 Applications for OpenOBEX
#ii python-bluez 0.16-1ubuntu1 Python wrappers around BlueZ for rapid bluet
#
#NOTES:
#The bluetooth connect seems to fail sometimes.
#Files with funny chars in name could cause a problem. maybe. () are okay
#Files to clear out are hardcoded.
#It's simple - just syncs files up if they don't exist on host.
#There are various other TODOs

DEVICENAME=$1
#echo all is $*
BTSYNCHOME=~/.btsync

# DEVICENAME can be blank (scans all devices)
HCISCAN=`hcitool scan |grep "$DEVICENAME" |grep -v ^Scanning `
#Scanning ...
# 00:1F:5D:BF:29:39 Nokia 3120 mmfa
# 00:17:E5:EE:29:18 Pooky
#check for duplicates
DEVCOUNT=`echo "$HCISCAN" |wc -l`
HCISCAN_S=`echo "$HCISCAN" |sed 's/[\t ][\t ]*/ /g;s/^ *//;'`
BTADDR=`echo "$HCISCAN_S" |cut -d' ' -f1`
DEVNAME=`echo "$HCISCAN_S" |cut -d' ' -f2-`

#echo "DEVCOUNT=$DEVCOUNT HCISCAN=$HCISCAN
#BTADDR=$BTADDR DEVNAME=$DEVNAME"

if [[ $DEVCOUNT -ne 1 ]] ; then
echo "usage: $0
e.g. $0 42:54:41:44:44:52 \"C:/Data/\"
Which device?
$HCISCAN
"
exit;
fi

echo "BTADDR=$BTADDR DEVNAME=$DEVNAME"
#sudo hcitool info $BTADDR

DIRTOSYNC=$2
# TODO pass in dir/file to sync on cmd line in $2
if [[ -z $DIRTOSYNC ]] ; then
echo "usage: $0
e.g. $0 42:54:41:44:44:52 \"C:/Data/\"
e.g. $0 \$BTADDR \"C:/Data/Images/\"
e.g. $0 $BTADDR \"C:/Data/Videos/\"
e.g. $0 42:54:41:44:44:52 \"C:/Data/Sounds/\"
"
DIRTOSYNC="C:/Data/"
#exit;
fi

mkdir -p $BTSYNCHOME

DIRTOSYNC_HASH=`echo "$DIRTOSYNC" |sed 's/[\/ \\"]/_/g'`
#obexftp -b $BTADDR -v -l ""
#obexftp -b $BTADDR -v -l "C:/"
echo DIRTOSYNC=$DIRTOSYNC DIRTOSYNC_HASH=$DIRTOSYNC_HASH
obexftp -b $BTADDR -v -l "$DIRTOSYNC" |tee $BTSYNCHOME/$DIRTOSYNC_HASH.list


# cd to where we are getting files
mkdir -p $BTSYNCHOME/$DIRTOSYNC_HASH
cd /tmp
cd $BTSYNCHOME/$DIRTOSYNC_HASH
pwd


echo get list of all files
echo TODO: parse xml safely/properly
#
#
FILES=`grep "echo FILES=$FILES

## forget about first retrieve or not, just check files on each system
#if [[ -f $BTSYNCHOME/$DIRTOSYNC_HASH.success ]] ; then
#echo for second/.. retrieve just get differences

echo TODO: recurse into directories

echo TODO get updated files, now we get new files only


function wipe_existing_files_from_list () {
echo for now we check if file exists already and wipe from list
##file list to retrieve by eliminating ones already retrieved
FILESTOGET=
for F in $FILES ; do
if [[ ! -f $F ]] ; then
FILESTOGET="$FILESTOGET $F"
fi
done
FILES="$FILESTOGET"
#diff $BTSYNCHOME/$DIRTOSYNC_HASH $BTSYNCHOME/$DIRTOSYNC_HASH.success
#mv $BTSYNCHOME/$DIRTOSYNC_HASH $BTSYNCHOME/$DIRTOSYNC_HASH.success
}

function get_the_files () {
if [[ ! -z $FILES ]] ; then
echo get the files
obexftp -b $BTADDR -v -c "$DIRTOSYNC" -g $FILES |tee $BTSYNCHOME/$DIRTOSYNC_HASH.get
# can obexftp do a dir? would be handy.
#obexftp -b $BTADDR -v -g "$DIRTOSYNC" |tee $BTSYNCHOME/$DIRTOSYNC_HASH.getdir
# also -G (get and delete) could be used for some files
fi
}



# TODO/half DONE track and check each file seperately
# TODO maybe if we got the file, store the associated line then in .success file
# use size/date in xml and on file system.
# ideally we want commands: GET[and remove] if newer/different

function track_the_files () {
#CHECKFILES=`echo $FILES |sed 's/ / && -f /g'`
#if [[ $CHECKFILES ]] ; then
# mv $BTSYNCHOME/$DIRTOSYNC_HASH $BTSYNCHOME/$DIRTOSYNC_HASH.success
for F in $FILES ; do
if [[ -f $F ]] ; then
# a file name which is part of others will cause problems
FILEINFO=`grep "> $BTSYNCHOME/$DIRTOSYNC_HASH.success
fi
done
}


## TODO cleanup all files on mobile retrieved this time or previous
## allows syncing as soon as possible but cleaning after longer (keep recent photos, traces, ...)

# cleanup files matching certain patterns on mobile if they were successfully retrieved
# we could use -G earlier (get and delete)
function clean_the_files () {
for F in $FILES ; do
###if [[ -f bin/eirkey.pl && ( -n ${FG#wami} || -n ${F%gpx} ) ]] ; then echo yep; fi

if [[ -f $F && ( -n ${F#wami*.gpx} || -n ${F#*.jpg} ) ]] ; then
obexftp -b $BTADDR -v -c "$DIRTOSYNC" -k $F |tee -a $BTSYNCHOME/$DIRTOSYNC_HASH.clean
fi
done
}

wipe_existing_files_from_list
echo files to get FILES=$FILES

get_the_files

track_the_files

clean_the_files