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

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.
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: if you don't already have it, unpack and sudo ./ install.

Unpack the google-blog-convertors package and:
bin/ -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 ..

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 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/ and buildTclLauncher.bat in src/*/ and build/

I've been evaluating using XQual XStudio as a test invoking tool. As opposed to Salome_tmf.

Files here:

| Class: CLauncher |
| |
| Developer: Eric Gavaldo ( |
| Jumbo |
| James Coleman ( |
| |

This file was created by changing the perl
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.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() {

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

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

// check the configuration sent by the manager

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,
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 Monday.
Finished with Sun Friday!
Kids all started back to school Tue.

script created just now:

TODO: cron job to daily sync phone


#$ [device [dir]]
#$ 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
#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
#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

#echo all is $*

# 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-`


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

#sudo hcitool info $BTADDR

# 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/\"

mkdir -p $BTSYNCHOME

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

# cd to where we are getting files
cd /tmp

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
for F in $FILES ; do
if [[ ! -f $F ]] ; then

function get_the_files () {
if [[ ! -z $FILES ]] ; then
echo get the files
# 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

# 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
for F in $FILES ; do
if [[ -f $F ]] ; then
# a file name which is part of others will cause problems

## 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/ && ( -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

echo files to get FILES=$FILES