June 07, 2007
Google maps overlay sites

Comments(0) | Print | Home

I read about map my run and tried it. There was a lot of registering involved and the UI over Google maps seemed to move the map around too much as I moved the cursor to do a route.

I mentioned the site to a friend and she suggested Gmaps Pedometer. This site is much simpler: you plot a route, save it and it returns a URL. Just the simplicity I need to find out how far I walked my dog or to lay out a 5k lunchtime jog.

 
Posted by jservice at 10:27 PM
April 27, 2007
Facebooking

Comments(0) | Print | Home

I guess it had to happen sooner or later…I joined Facebook. Facebook disallowed Service. First I used Ecivres, then changed it to Serçice then I noticed my son had the right name so I sent an email got the correct last name.

I have “connected” with a couple of cousins that I haven’t seen since they were little kids.

Come on over and be my friend. smiley)

 
Posted by jservice at 09:41 PM
April 18, 2007
New dishwasher delivered

Comments(0) | Print | Home

The door springs broke on the old dishwasher and the door is so heavy that one side bracket cracked the side of the door. We bought a new one since this old one has lasted over twenty years.

I uncrated the new Maytag model and put it in the space where the old one was. Two problems: the hot water fitting is in a different place so that I either have to cut the copper pipe or, my preference, use a stainless steel flexible line. I note that there is already a union in that pipe so I must have lengthened it when I installed the old dishwasher.

The other problem is that the sound deadening package of plastic and rubber flanges require an opening of just 24 inches. I’ll have to do some shimming of the opening and the kick plate area.

I guess I’ll be washing dishes in the sink for a few more days more.

 
Posted by jservice at 10:13 PM
April 06, 2007
Another use for rsync

Comments(0) | Print | Home

I use rsync on my Unix boxes to archive or update directories on different host machines. Recently I have started using it to synchronize directories between my Windows boxes at work and at home (through the VPN) via the SAN drives. This works quite well, especially for files such as large Word documents as the format just seems to include new stuff in chunks so that the rsync algorithm need only update the changes. Using the -z compression switch also helps to speed the transfer.

I include a short file I’ll call rsync.sh. I run bash in cygwin and paste in the appropriate line. I keep the -n switch so that no action will take place initially and I’ll recognize whether the list of files to be transferred looks correct.

# remove -n to do the operation
# home to work
rsync -n -Cavz --stats /cygdrive/c/home/jservice/work/DIR /cygdrive/h/network/
# work to home
rsync -n -Cavz --stats /cygdrive/h/network/DIR /cygdrive/c/home/jservice/work/
# network to desktop
rsync -n -Cavz --stats /cygdrive/h/network/DIR /cygdrive/d/work/
# desktop to network
rsync -n -Cavz --stats /cygdrive/d/work/DIR /cygdrive/h/network/
 
Posted by jservice at 04:12 PM
March 07, 2007
Remote controlling

Comments(0) | Print | Home

At work I used VNC to connect from my desktop PC to another win2k box in a lab a floor and a building away. From that box I dialed out using PCanywhere to a win2k box in a transformer station near Sudbury.

Today it was a Terminal Services client through the VPN to a win2k server box. From there I used Putty as an SSH client to connect to a FreeBSD box. Then I ran screen on that.

 
Posted by jservice at 08:05 PM
September 15, 2006
Where have the Enter and Esc keys gone in my dialog box?

Comments(0) | Print | Home

I spent almost a day trying to find out why my dialog in Borland C++ was closing with the press of an <Enter> or <Esc> key. When I set a break point I found those keys weren’t even being seen by the dialog. Finally after considerably searching I found that controls such as buttons have a Default property. If this is true then <Enter> or <Esc> will automatically press that button. Thanks for making this clear!

 
Posted by jservice at 11:11 PM
August 08, 2006
Yes I regretted re-enabling comments

Comments(0) | Print | Home

Sheesh! I re-enabled comments and then went away on business for a week. Though I did have Internet at some of the hotels I discovered that MT-Blacklist didn’t work on the server. There were at least 800 comment spams added.

Finally, this weekend, I exported my entire blog. I wrote a Perl script to remove the offending comments and to close all commenting. I started to tediously delete all the old entries until I found that the Web Developer Toolbar for Firefox could automatically populate all the delete boxes.

So, the blog is renamed and all the comments are closed. Now you commentors will have to email jservice (at) gmail (dot) com if you would like me to add your comment.

 
Posted by jservice at 12:03 AM
July 22, 2006
Comments working again

Comments(0) | Print | Home

When this blog switched servers, the Email::Valid module was missing. Now I’ve put it back and comments can be made. (Will I regret this?)

 
Posted by jservice at 10:51 PM
July 19, 2006
Mp3 player ain't

Comments(0) | Print | Home

It doesn’t seem to turn on no mo'.

I didn’t use the mp3 part much; but, I miss listening to CBC Radio One while commuting to work already.

 
Posted by jservice at 10:06 PM
July 15, 2006
Multiple copies of rows in PostgreSQL

Comments(0) | Print | Home

I had a rather complicated view where I needed to duplicate each row and change one column in every other row. I came up with this function:

-- Function: numbers(count int4)

-- DROP FUNCTION numbers(count int4);

CREATE OR REPLACE FUNCTION numbers(count int4)
  RETURNS SETOF int4 AS
$BODY$
BEGIN
  -- Usage: select * from numbers(10)
  -- returns a column of integers from 0 to 9
  --
  for i in 0 .. count - 1 loop
    return next i ;
  end loop ;
  return ;
END ;
$BODY$
  LANGUAGE 'plpgsql' IMMUTABLE;

To make 3 copies of each row of table I could use the following:

select * from mytable,numbers(3)
 
Posted by jservice at 10:31 PM
June 26, 2006
Rub a dub dub I painted the tub

Comments(0) | Print | Home

An estimate for replacing tub, taps, wall tiles and adding floor tiles amounted to $5k! This didn’t include a new toilet, vanity or light fixtures. For about 1% of that amount I spent the weekend cleaning and epoxy painting the tub. Looks pretty good. Now I have to wait a few days while the paint cures and then re-caulk.

 
Posted by jservice at 10:42 PM
June 06, 2006
Data reduction

Comments(0) | Print | Home

A client provided an MS Access export of their asset database: a table of 330,000 rows by 77 columns. Good ol' Access felt these data needed over 2 Gbytes of storage. I exported the table as a CSV file, about 143 Mbytes and then imported it into PostgreSQL. It needed only 240 Mbytes or so. Queries are much faster than with Access, too. When I made a compressed backup (dump) of the table from PostgreSQL only a modest 7.9 Mbytes was required.

 
Posted by jservice at 10:09 PM
May 28, 2006
3 holes, 3 poles

Comments(0) | Print | Home

Finnegan, our dog is wearing out our backyard. And we can’t let him out after a rain as he’s worn down the grass to the bare clayey soil. So, I’m partitioning off, with chain link fencing, part of the back yard and the west side yard for a dog run.

Forked tree root removed.jpgRemoved tree root and saw that did it.jpg

Yesterday it took me an afternoon and evening to put in 3 six inch by 27 to 30 inch holes. The middle hole was the “easiest” as there were no large rocks or roots. Just a thunk, scoop, thunk, scoop with the post hole digger. The first hole had several tree roots along the way and several larger stones to extract. Once I cut the forked tree root at the top of the third hole the thunking part wouldn’t work. I needed to use my 3 foot crowbar to “loosen” up an inch or so of clay and then use the post hole digger to extract this. This was all very laborious and time consuming. However, I doubt a power auger would have worked in our heavy clay.

Today I set the three poles in the three holes with quick setting post-hole concrete. I didn’t even need to stake the last pole vertical as the concrete had all ready set enough. For the other two poles I found my heavy pipe clamps laid on the ground were sufficient to hole the fence posts in place.

 
Posted by jservice at 10:42 PM
May 21, 2006
Probably not compost lumps next time

Comments(0) | Print | Home

I sifted the compost yesterday and, since there were no stones, I thought I would run the lumps (sticks, grass roots, pits, etc) that didn’t sift through the chipper / shredder (CS). However it has been raining a lot lately and there was enough sticky clay to gum up the works. Once I stopped the engine I couldn’t restart it. At least I have taken the guard off the CS before so it didn’t take me long to clean out the gunk. And, yes the lumps are smaller now and mixed up with weed and twig bits ready for some more composting action.

 
Posted by jservice at 09:54 PM
May 11, 2006
Back blogging again

Comments(0) | Print | Home

My son’s server died so he had moved my home directories including this blog over to a different server. However, the set up and permissions for the cgis to run the blog updates weren’t set correctly. I have been just a tad too busy to solve the problems until tonight.

 
Posted by jservice at 09:56 PM
March 29, 2006
wperl.exe and STDOUT

Comments(0) | Print | Home

I write a lot of Perl scripts that run periodically in the background through the so-called Task Scheduler. Each of these scripts appends to a log file and sends a one-liner to the next-to-useless Event Log to report the path to this log file. I redirect STDOUT and STDERR to the log file so that everthing gets set there. This all works fine using perl.exe but not with wperl.exe the “non console” version of perl.exe. Today I found out why.

In wperl.exe fileno(STDOUT) returns -1, an invalid file handle number. So, you have to close(STDOUT) and then open(STDOUT, “>>$log_file”). In perl.exe I would open(LOGFILE, “>>$log_file”) and then open(STDOUT, “>&LOGFILE”). Now I can run (w)perl scripts at user logon/off and system startup/shutdown events and still have some logs to look at if something goes awry.

 
Posted by jservice at 10:03 PM
March 19, 2006
Logging receipts for income tax purposes

Comments(0) | Print | Home

For the last four years I have been using an Excel spreadsheet to log the receipts for my wife’s music teaching business. In previous years I’d log each receipt with a code (ele - electricity bill, os - office supplies, etc), the date and the amount. Then I would sort this list of 200 - 300 items by code and date and confirm that I have each month’s utility bill. Each of those ranges I would name, sum them and name the sums: a lot of work, especially if I found another receipt or two.

This year I’m using DSUM and DCOUNT the “database like” functions of Excel. Now I don’t need to sort the receipts anymore. I just select on the codes to get the various sums. I also downloaded all 2005’s worth of chequing account transactions from my credit union in the form of a spreadsheet. Again I could use DSUM and DCOUNT to select and sum all the automatically deducted utility bills. After an afternoon (most of that was spent setting up the DSUM magic) and an evening’s work that part is done—a process that has taken me several weekends in the past.

 
Posted by jservice at 11:06 PM
February 11, 2006
A solution to afterpage not working inside longtable

Comments(0) | Print | Home

I wrote an ISO9000:2000 internal audit report which is basically a long table of section numbers from the standard, brief descriptions, a rating and my observations; especially if I rated the section UNSatisfactory. I used LATEX (LaTeX) to typeset the report and found that the \afterpage macro doesn’t work in \longtable. I usually use something like this on the title page:

\lhead{}\chead{}\rhead{\putlogo}
\afterpage{\chead{\MyTitle}}

After some head-scratching I came up with the following using the \ifthenelse macro to achieve the same effect. Now the header logic is inside the header itself.

\lhead{}\chead{%
  \ifthenelse{\equal{1}{\thepage}}
    {}
    {\MyTitle}}\rhead{\putlogo}
 
Posted by jservice at 05:26 PM
January 01, 2006
Knots

Comments(0) | Print | Home

Scouts-Logo.gif

Through the This is True email list I found this standard scout knot site with animations.

The only missing knot was something with which to tie down your canoe to the car roof racks. The driver’s hitch, here or here would seem to be suitable though I use a simple overhand loop which, admittedly, gets very difficult to untie at the end of a couple of hundred kilometers. I don’t normally make New Year’s Resolutions; however, I might learn this knot…and the one I found for tying fishing line to a fish hook.

 
Posted by jservice at 03:16 PM
December 31, 2005
Last day of 2005

Comments(0) | Print | Home

Well, it seems I have either a) lost interest, b) lost time, c) found other things to do or d) all of the above with respect to this blog. My first post was way back on Feb. 25, 2002. Our dog, now almost one year old, accounts for b) and c) as well as becoming choir manager, and a) arises because, after walking the dog in the evening, I don’t feel much like spending another half an hour posting something.

Perhaps I should try posting just a sentence or fragment instead of paragraphs.

Anyway, my software find this week is Audacity. I decided to start digitizing choir concert tapes from years ago. I can record one side of a tape and then slice out the selections, creating mp3 files out of them. So far I have done one Bell’Arte Singers set of two tapes from Nov. 1998 and one Toronto Chamber Society concert from Nov. 1981. The TCS turned out all right. The BAS tapes have either been played too much or they weren’t recorded at a high enough level. Their sound is kind of rumbly and muddy. I tried the FFT filter from the Audacity library to cut out the low frequencies: less rumbly now but the vocal sounds still aren’t very clear.

As for the 1981 tape, I don’t have the program just the titles I wrote on the cover. Through the “miracle” of the Internet though, I can search for midis based on the titles and, from listening to those, I can determine the correct title and composer.

 
Posted by jservice at 12:31 PM
December 18, 2005
Kill the console window

Comments(0) | Print | Home

I have an hourly scheduled set of commands that take between 15 and 20 minutes to complete on my work PC. I found out how to automatically start the cmd with the console minimized. Just recently I discovered how to get rid of the window entirely using Win32::GUI:

@perl -MWin32::GUI -e "$dos = Win32::GUI::GetPerlWindow() ; Win32::GUI::Hide($dos)"

Now I would like to find a or write a small NotifyIcon application to which other processes can talk and change either the icon or the tooltip in order to report the status of those processes running in the hidden console window.

 
Posted by jservice at 08:59 PM
November 27, 2005
Missing ~ ... again, argh!

Comments(0) | Print | Home

Hmmm, I forget a ~ yet again in my Perl code and spent quite a while trying to figure why a variable was empty. Sheesh!

# The following means assign $b the "success" of $_ =~ s/.dat// 
# whatever $_ is at this point
$b = s/\.dat// ;
# This is a regexp substitution: remove first occurrence 
# of ".dat" from $b.
$b =~ s/\.dat// ;
 
Posted by jservice at 10:55 PM
November 25, 2005
Mail merge add-in install woes

Comments(0) | Print | Home

A colleague wanted to send out a mass email with attachments announcing a new piece of test equipment. I looked at a few packages and finally decided on Mail Merge Toolkit as having the necessary features to link a MS Word merge with email. Well, it came time to do it today and I find out the colleague uses Work 97 and this add-in only works for Word 2000 and above. Sigh. Since we are on a common domain he logged on to my machine and I tried the installation and merging using his account. Another sigh. He didn’t have admin rights so the install was incomplete. I had to log in as myself put him in the admin group and then get him to log in again. Finally I managed to send out the 131 emails with “glossy pdf” attachment.

It had to be done today because he is going on an extended vacation using up banked days until sometime next June we he officially retires. Me, I can only recall one or two years of the almost 30 when I might have banked a few days. I’m of the school where vacation is meant to be taken and enjoyed in the year that it is granted.

 
Posted by jservice at 11:17 PM
November 08, 2005
Googled the website

Comments(0) | Print | Home

This past weekend I added Google site search to the company website. This replaces the “so Twentieth Century” local search engine. Now the PDFiles and DOCuments are indexed, too.

 
Posted by jservice at 10:38 PM
October 23, 2005
Rain barrel setup

Comments(0) | Print | Home

VersionImageComment
1.0rainbarrel-v1.0.jpgAs set put together one evening in the dark with a flashlight since rain was predicted the next day.
1.1rainbarrel-v1.1.jpgI realized I wouldn’t be able to empty the barrel completely if it was on the ground so I put it up on the two surplus concrete steps I had lying around.
1.2rainbarrel-v1.2.jpgI found the barrel would fill in a couple of hours on a rainy day and the overflow hose would make a big puddle. I now send the overflow down the original drainpipe drain.
 
Posted by jservice at 09:50 PM
October 16, 2005
New ground floor windows

Comments(0) | Print | Home

E-FR-window.jpgNW-FR-window.jpgSW-FR-window.jpgKitchen window and new siding1.jpgLR bay window.jpg

The old windows were replaced last month; however, I hadn’t had the chance to take pictures until yesterday. My favourite is the large awning window in the kitchen. When we were cooking for 20 on Thanksgiving, I could cool off the kitchen with the ceiling fan and opening the window. The old window here was a sticky-side slider which we eventually gave up using.

“Siding” the kitchen window and living room window eliminates two more outside paint jobs. Though the thermostat has been switched to “heat” it hasn’t come on at all yet because these window insulate so much better than the old ones. These windows, as well as being low-E and better insulated, are also “self-clean”, too.

 
Posted by jservice at 09:12 PM
September 29, 2005
Browser comparisons #5436

Comments(0) | Print | Home

Firefox-logo.pngie-logo.png

I tried to print a page from one website, an IBM developer article I think, and, no matter how I shrunk it, part or all of some of the words in the right margin were cut off. This was in Firefox. I tried IE —same result. Since Opera is now free and I had recently installed it, I tried this browser. Success, all the paragraphs were displayed, however, I should have “print previewed” the whole document as Opera gave me 10 extra neatly numbered, URL titled, marked and dated blank pages!

Opera4.png
 
Posted by jservice at 08:57 PM
September 21, 2005
File naming for weekly logs

Comments(0) | Print | Home

coloured log view.png

I wrote a script to format “per channel, hourly” statuses into an Excel spreadsheet and an html table using variously coloured boxes to show the status (good, fair, poor, no data, etc). It was easy enough to date the “past week” files with the current day-date in the file name. However, after a couple of months, there are a number of these daily files, each with 6 days worth of redundant data. Yesterday I wrote a small function to return the timestamp of the Saturday for the current week’s data. Now I will have only one weekly spreadsheet and html file per week showing that week’s status.

The Perl function is quite short:

# Index of date numbers returned by localtime.
%DATE_INDEX = (isdst => 8, yearday => 7, weekday => 6, 
               year => 5, month => 4, day => 3, 
               hours => 2, minutes => 1, seconds =>0) ;
$_ONE_HOUR = 60*60 ; # seconds/hour
$_ONE_DAY = 24 * $_ONE_HOUR ; # seconds/day
# ...
sub week_ending_time ($) {
  # Given a serial time find the time on the next Saturday.
  my $time = shift || time ;

  # Add number of days until next Saturday.
  $time + (6 - (gmtime($time))[$DATE_INDEX{weekday}])*$_ONE_DAY ;
}

I also wrote a PostgreSQL function equivalent:

CREATE OR REPLACE FUNCTION week_ending_date("timestamp")
  RETURNS "timestamp" AS
$BODY$select date_trunc('day', $1) + (6-(date_part('dow', $1)) || ' days')::interval
$BODY$
  LANGUAGE 'sql' VOLATILE;
 
Posted by jservice at 11:21 AM
September 03, 2005
Throwing out history

Comments(0) | Print | Home

This Labour Day long weekend, at the end of my August vacation (except for being called in 5 days to work!), I wanted to clean up the garage. There are pieces of drywall and birch veneer particle board, for example, that have been moved (and re-moved) from my first house where my oldest son was born. I think that after 25 years, most of this stuff has got to go. That drywall was used to repair a wall in my older son’s nursery and the birch veneer particle board was used for kitchen cabinets in our first house. I’m not sure why I moved three 4' x 8' x 1½”sheets of styrofoam insulation from the last house or why I bought it in the first place. Anyway, I’ve cut it up to put out for recycling and and generated lots of bits of styrofoam chips to sweep up. Through experimentation, I found a hand saw works best. The serrated knife generated too many styrofoam bits and required more effort.

Tomorrow I’ll use my table saw or chop saw to cut the scraps of wood to length to bundle up for the garbage.

No pictures because a) I forgot to take one “before” and b) unless you were the one trying to find something in the junk, the picture wouldn’t tell the story.

 
Posted by jservice at 10:28 PM
August 29, 2005
Latest toy, er tool

Comments(0) | Print | Home

I had several ½” holes to drill into the brick in my house in order to “sturdy up” and “verticalize” the deck railings with some brackets. It took an hour to go in about ½” with my 3/8” 2-speed drill (a wedding present to me from my best man, btw). I brought out my other drill but it happened to fall off the railing and crack the handle. I considered this an omen: go out and buy yourself a hammer drill. So I did.

It took me about 15 minutes to do the four holes I required with that tool. I should have bought one years ago. For example, it took me most of the day to drill a 5/8” hole through the foundation wall of my previous house to add a new outside hose tap. I was swapping my two drills as one would get too hot to hold. I suspect that with a hammer drill it might have taken 15 minutes, tops.

Duct tape, “the handyman’s secret weapon,” fixed the drill’s handle.

 
Posted by jservice at 10:17 PM
August 11, 2005
Vacationing at work

Comments(0) | Print | Home

I hate being indispensable when I’m supposed to be on vacation!

First it was a power outage and then a drastic change in IP address from the infamous sympatico.ca prevented data getting through for a few days while I was canoing in Algonquin Park. I spent a day fixing this.

Then, coincidently, bad blocks appeared on the root partition of my server and it wouldn’t boot after yet another local power outage. So we purchased to new brand new hard drives. One of them I put in the old server and made the old disk a “slave.” Then I used the FreeBSD miniinst CD to install the OS on the new disk. Then I could rsync all of /usr from the old to the new drive. I also rsync'd /var/log, too. Finally I had to tweak the /etc files. Fortunately I had a backup copy as / was hosed on the old drive. The new and improved server worked fine once it was re-installed in the so-called DMZ at work. Thus ended the second day.

Today I “constructed” a backup server with that other new hard drive installed in another surplus office computer. This was somewhat slower install because, after I had installed the OS from the miniinst CD I had to bring over the rsync executable from the other server. Then I rsync'd /usr and /var/log over the network. As left this backup server will mirror the original server so that, hopefully, I’ll be able to swap if the original server dies. So endeth the third day.

I “pretended” I was on vacation by walking the dog first, picking up a coffee on the way, and coming in to work later wearing shorts and sandals. Oh well, this means three more vacation days later on.

 
Posted by jservice at 11:00 PM
July 20, 2005
My first PostgreSQL trigger function

Comments(0) | Print | Home

I wrote a trigger function today to “audit” a table of readings I’ll call mydata which has new records automatically INSERTed by a script. Occasionally there are “funny” entries which I have to manually fix up using pgAdmin III's grid widget. However, I wanted some way of keeping track of the old changes in a log table. So, I wrote this trigger function to generate an update query which would change the modified record back to the old one. The trigger fires on updates to the mydata table each time I edit a row.

CREATE OR REPLACE FUNCTION mydata_update()
  RETURNS "trigger" AS
$BODY$BEGIN
-- Add an entry to mydata_log about the old data.
insert into mydata_log (date,channel,outer_channel,rdg_date,rdg_hour,comment)
values (OLD.reading_stamp,OLD.channel,OLD.outer_channel,OLD.rdg_date,OLD.rdg_hour,
        -- Generate an SQL list values of not already in other fields of the log table
        'UPDATE mydata SET '
        || 'reading = ' || OLD.reading
        || ',' || 'reading_diff = ' || OLD.reading_diff
        || ',' || 'reading_valid = ' || CASE WHEN OLD.rdg_valid THEN '''t''' ELSE '''f''' END
    || ',' || 'perl_time = ' || OLD.perl_time
        -- quote the timestamp
        || ',' || 'modified = ' || '''' || OLD.modified || ''''
        || 'WHERE ' || 'id = ' || OLD.id
        ) ;
-- Set modified field to now.
NEW.modified := CURRENT_TIMESTAMP ;
-- Continue with the update
RETURN NEW ;
END ;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
 
Posted by jservice at 10:42 PM
July 15, 2005
Rediscovering Spreadsheet::WriteExcel

Comments(0) | Print | Home

spreadsheet.png

I had to display a matrix of data, about 100 channels vs several days of sampled hours where some channels have good data, some have partial data and others don’t have any data. These data items are hourly residential meter readings and it is important for the hardware guys to spot which meters are sending data and which aren’t. As I was parsing and finding this data with Perl, I realized I could use the Spreadsheet::WriteExcel module to format it. That way I could colour code the different categories of meter readings and hide rows of extra data or noise found in the original “transmission.” It is obvious from the red lines on the image that there are some problem channels.

 
Posted by jservice at 10:50 PM
July 05, 2005
My ISP blocking outgoing port 25?

Comments(0) | Print | Home

Newest daylily bloom.jpg

It looks like Rogers is blocking outgoing SMTP (port 25) traffic.

There goes my nice little FreeBSD server I used to help my fellow choir members send out messages to each other. I was the only one who had to maintain a list of 50 or so members and all the rest could send to everyone using just one email address.

 
Posted by jservice at 09:12 PM
June 20, 2005
PostgreSQL: returning an item from an arbitrary table

Comments(0) | Print | Home

I have several PostgreSQL tables of readings in a database which all inherit from the same base table so that they all have the same columns. I wanted to define a function to return the maximum value of a particular column from an arbitrary table. The EXECUTE command doesn’t work because it doesn’t “trap” it’s output. After some Googling and reading, I finally came up with the answer using FOR-IN-EXECUTE:

CREATE OR REPLACE FUNCTION get_timestamp(text)
  RETURNS "timestamp" AS
$BODY$DECLARE
  max_ts timestamp ;
  rec record ;
BEGIN
  FOR rec IN EXECUTE 'SELECT max(reading_stamp) as mx FROM ' || quote_ident($1) LOOP
    max_ts := rec.mx ;
  END LOOP ;
  RETURN max_ts;
END ;$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
 
Posted by jservice at 10:32 PM
June 17, 2005
Suppressing the cmd (console) window

Comments(0) | Print | Home

I run some Perl scripts from the Windows Scheduled Tasks control panel applet. I have always had the cmd window pop up while the script is running which can be quite annoying. Today I found how to suppress or at least minimize the window by adding the start command:

cmd /c start "My Task" /min c:\Perl\bin\Perl.exe c:\scripts\myperlscript.pl arg1 arg2

Now the cmd window appears very briefly and the perl process gets minimized to the task bar.

 
Posted by jservice at 10:35 PM
June 10, 2005
Those merging code blues, hot

Comments(0) | Print | Home

Finnegan and his footwear 2005Jun8.jpg

I made a copy of a Perl module I’m developing so I could make it faster and test it thoroughly before I merged it with the production code. Today I merged the production and new and improved modules and discovered one tiny change I made for testing and sorting convenience: $hash{key_a}{ke_yb} to $hash{key_b}{key_a} would seriously “break” the main calling program. Fortunately I had checked in my old versions as I went so I could restore the previously working versions of the calling program and production module. It’s kind of depressing to do this on a Friday afternoon, though — especially since I’ll be tied up doing Health and Safety auditing next week.

I see that Chiang Mai, Thailand where my brother teaches, has about the same temperatures, low 20’s to high 30+, as we do.

 
Posted by jservice at 10:03 PM
June 09, 2005
Convert some integers to BCD bytes

Comments(0) | Print | Home

I needed to convert a timestamp (seconds, minutes, hours, day, month, last 2 digits of the year) into a BCD string of bytes. Here’s the Perl sub I came up with to do that:

sub bcd_timestamp_string (@) {
  # Convert given time or local time to BCD bytes
  my @time = @_ ;

  join('', map {
    pack('H*',sprintf('%02d',$_))
  } @time) ;
}
2005-06-09 Irises in front garden.jpg
 
Posted by jservice at 09:47 PM
May 21, 2005
Can I get there from here?

Comments(0) | Print | Home

I was too tired to comment on the table I put up last night comparing four routes from work to a place near the transformer station I worked at last Wednesday. I already knew the way but I wanted to see what the web map sites said.

Leaside Bridge

Both Google and Yahoo! suggest the same basic route through downtown Toronto. Perhaps those times (20 or 26 minutes) are realistic at 3 a.m; however, with traffic lights, street cars and traffic “calming” on a couple of streets I would probably allow an hour for this route. Mapquest recommends the route I usually take. Except for rush hour, I would probably allow just ½ an hour for this route. The Maporama route starts similarly to the Mapquest until this direction: Follow Don Valley Pky for 6 km, Turn left, follow Millwood Rd. I have an image of that left turn which seems to include a 30 m vertical climb as well.

I do like Maporama street maps because they include house numbers: just don’t ask for directions!

 
Posted by jservice at 09:10 PM
May 20, 2005
800 Kipling Ave to 86 Laird Drive

Comments(0) | Print | Home

Google Yahoo! Mapquest Maporama
18 km, 20 mins 18.2 km, 26 mins 27.2 km, 25 minutes 24.1 km, 18 min.
1. Head northwest from Kipling Ave - go 1.2 km
2. Turn right onto the Dundas St. East ramp - go 0.1 km
3. Bear left at Dundas St W - go 3.9 km
4. Turn left at Scarlett Rd - go 0.1 km
5. Turn right at St Clair Ave W - go 8.8 km
6. Continue on St Clair Ave E - go 0.9 km
7. Turn left at Mt Pleasant Rd - go 0.4 km
8. Turn right at Moore Ave - go 1.5 km
9. Continue on Southvale Dr - go 0.8 km
10. Turn left at Laird Dr - go 0.3 km
1. Start at 800 KIPLING AVE, ETOBICOKE going toward NORSEMAN ST - go 1.4 km
2. Turn right onto DUNDAS ST W toward DUNDAS ST. EAST - go 4.0 km
3. Turn left on SCARLETT RD - go 0.2 km
4. Turn right on ST CLAIR AVE - go 9.7 km
5. Turn left on MT PLEASANT RD - go 0.3 km
6. Turn right on MOORE AVE - go 1.6 km
7. MOORE AVE becomes SOUTHVALE DR - go 0.6 km
8. Continue on MILLWOOD RD - go 0.2 km
9. Turn left on LAIRD DR - go 0.3 km
10. Arrive at 86 LAIRD DR, E YORK
1: Start out going SOUTH on KIPLING AVE toward JUTLAND RD. 1.0 miles
2: Take the GARDINER EXPWY. EAST ramp. 0.3 miles
3: Merge onto GARDINER EXPY COLLECTORS E. 1.2 miles
4: GARDINER EXPY COLLECTORS E becomes GARDINER EXPY E. 8.1 miles
5: Merge onto DON VALLEY PKWY N via the exit on the LEFT. 4.2 miles
6: Take the DON MILLS RD. SOUTH exit. 0.1 miles
7: Turn SLIGHT RIGHT onto DON MILLS RD. 0.2 miles
8: Turn RIGHT onto OCONNOR DR. 0.1 miles
9: Turn SLIGHT RIGHT onto DONLANDS AVE. 0.3 miles
10: DONLANDS AVE becomes MILLWOOD RD. 0.7 miles
11: Stay STRAIGHT to go onto LAIRD DR. 0.1 miles
12: End at 86 Laird Dr
1 Follow Kipling Ave for 1.3 km 1.3 km 00h 01
2 Turn left, follow Gardiner Expy for 15.4 km 16.7 km 00h 12
3 Follow Don Valley Pky for 6 km 22.6 km 00h 16
4 Turn left, follow Millwood Rd for 1.2 km 23.8 km 00h 18
5 Follow Laird Dr for 236 m 24.1 km 00h 18
 
Posted by jservice at 10:41 PM
May 19, 2005
Restarting PC Anywhere automatically

Comments(0) | Print | Home

There are about 8 Windows 2000 equipped PC’s at transformer stations about the province measuring GICs. I have fixed the software and upgraded some drivers to make them work better. However an older version of PC Anywhere would die under mysterious circumstances so that one couldn’t contact the machine anymore unless it happened to reboot. Many of these TSs are unmanned and remote so you can’t just call someone to press the reset button. Today I figured out one work-around that should have been used from the start. I added a new Scheduled Task to run once every ½ day:

net start "pcanywhere host service"

Either one of us a work has to drive out to the two remaining stations and upgrade the software or, perhaps, we can convince some travelling operator or service person to reset the machine so that we can call it again and add my work-around. Then we can download the software and driver upgrades at our leisure, so to speak. I’m not sure how PC Anywhere upgrades itself when you run setup over an old version of PC Anywhere though.

 
Posted by jservice at 09:51 PM
April 29, 2005
Overlaying with dia, site ranking

Comments(0) | Print | Home

A manager wanted to present a talk on our 50 home test trial we are doing in a town near here. The local utility’s AutoCAD drawing was unsuitable because of over[too much information]{TMI}. Instead, I saved a couple of the XXL images from Maporama. Though I prefer Google maps for finding my own way around, the maps are really a collection of small images so you have to use a screen capture to grab the whole map. Maporama also has a nice feature at higher zoom levels by annotating with street numbers. This made it easy to cross-reference with the utility’s AutoCAD drawing. Once I had the map images, I used dia to import the images, adjust them so they made a continuous map and then mark our test trial locations with text notations.

Selected Netcraft toolbar page rankings
SiteRank
Work82,203
This site270,763
Google1
 
Posted by jservice at 10:33 AM
April 22, 2005
Binmode

Comments(0) | Print | Home

There are still vestiges of DOS in Windows XP. I was merrily parsing several hundred 256k binary files in Perl with this script until it failed to read in the whole file one day. It got stuck on a cr-lf combination even though I was using a sysread call. I had (forgotten?) to use binmode FILE; right after I opened the file. Of course this is a NOP in every other type of Unix where text and binary files are treated just the same when reading raw bytes.

 
Posted by jservice at 09:57 PM
April 13, 2005
2004 tax returns finally filed

Comments(0) | Print | Home

I took a day off using up some lieu time and finished up the taxes for my younger son, myself and my wife. I’m looking forward to that refund already!

 
Posted by jservice at 12:52 PM
April 01, 2005
iRiver firmware updated

Comments(0) | Print | Home

My little MP3/WMA player, FM Tuner is now, effectively, a removable USB drive. I don’t need to use iRiver’s application anymore to load it up with music files for on the road. Right now it has the Handel’s Messiah choruses for parts 2 and 3 to re-familiarize myself for upcoming performances with a “pick up” Oakville choir and orchestra on April 13 and 15, 2005 at St. Andrew’s Church in Oakville.

 
Posted by jservice at 09:50 PM
March 30, 2005
Report sent to client

Comments(0) | Print | Home

Finally all the immediate work FY2004-5 deadlines have been met:

  • Draft report submitted to client.
  • Client billed final amount.
  • Year end timesheet filed.
  • The snow is finally disappearing and spring is on its way. I can run with just two layers and a baseball cap and consider in-line skating again.

All is not bliss, though, as there’s still income taxes to file, an internal quality audit to conduct and a bundle of transfer of technology information to be assembled for another client.

 
Posted by jservice at 10:24 PM
March 29, 2005
Working from home

Comments(0) | Print | Home

Finnegan

My wife is back at work today after her March break. Thus I’m working at home so I can take the puppy out from his crate every so often. I just sent off a report I worked on yesterday and this morning to my boss. Though I’d love to run outside in the milder weather I think I only have an hour or so before the puppy needs to go out to do his “business.”

Today’s Firefox extension is a spell checker for textareas Spellbound. I can right click as I’m writing here and check the spelling.

 
Posted by jservice at 11:07 AM
March 09, 2005
Quickie Emacs mode for custom log file viewing

Comments(2) | Print | Home

I create log files with a custom Perl module and I decided to investigate creating an emacs “mode” in which to view them so that it would emphasize the warnings, for example. I found a tutorial on how to create a custom mode. At the very bottom of the article was a much easier way: deriving from an existing mode. Here’s my “quickie” mode for viewing my log files:

;;;;;;;;;;;;;;;;;;;;;;;;;;; -*- Mode: Emacs-Lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 
;; jrrs-event-log-mode.el
;;
;; A mode to highlight parts of the log files I create with JRRS::eventlog.pm
;; 
;; Author             : James R.R. Service
;; Created On      : Wed Mar 09 2005
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defconst elog-font-lock-keywords1
  (list
   '("\\<\\(info\\|debug\\)\\>" . font-lock-comment-face)
   ;; bring out embedded \n
   '("\\\\n" . font-lock-constant-face)
   ;; Bring out today's date by using ` and , operators to eval before adding
   ;; to list.
   `(, (concat "\\<" (format-time-string "%Y-%m-%d")
               " [0-9][0-9]:[0-9][0-9]:[0-9][0-9]\\>")
       . font-lock-function-name-face)
   ;; Emphasize WARN and DIE messages.
   '("\\<\\(WARN\\|DIE\\)" . font-lock-keyword-face)))

(defvar elog-font-lock-keywords elog-font-lock-keywords1
  "Highlight regexps for ELOG mode."
  )
;; (setq elog-font-lock-keywords elog-font-lock-keywords1)

(define-derived-mode elog-mode fundamental-mode "ELOG"
  "Major mode for view log files created by JRRS::eventlog.pm"
  (set (make-local-variable 'font-lock-defaults) '(elog-font-lock-keywords))
  )

(add-to-list 'auto-mode-alist '("\\.log\\'" . elog-mode))

(provide 'jrrs-event-log-mode)
 
Posted by jservice at 09:08 PM
March 07, 2005
Todays Postgres constraint

Comments(0) | Print | Home

Bad temperature readings appear as 4’s or 31.5’s. But if the rdg_valid flag is already false or the reading is an 'a' or 'b' code I want to accept the row. I only want to reject the row if it is a 'T' reading outside of the range 4.5 to 31.

ALTER TABLE my_table 
  ADD CONSTRAINT temperature_in_range 
  CHECK (NOT rdg_valid 
         OR reading_type_code = 'a' 
         OR reading_type_code = 'b' 
         OR reading_type_code = 'T' 
         AND reading >= 4.5 AND reading <= 31);
 
Posted by jservice at 10:09 PM
March 02, 2005
Views and Functions

Comments(0) | Print | Home

Today I replaced a bunch of Postgres database views like this:

CREATE OR REPLACE VIEW readings_last30d_daily_0 AS
SELECT rdg_date
       , to_char(sum(reading_diff)/1000.,'FM999990.999') as kwh_per_day
  FROM readings
  WHERE channel = 0 and rdg_valid
  AND reading_stamp between 
    (select max(reading_stamp) from readings
     where channel = 0 and rdg_valid) 
     - interval '31 days' 
  AND (select max(reading_stamp) from readings
       where channel = 0 and rdg_valid)
GROUP BY rdg_date ORDER BY rdg_date ;

with a function:

CREATE OR REPLACE FUNCTION readings_daily(text, int4)
  RETURNS SETOF date_rdg AS
$BODY$ SELECT readings.rdg_date
  , to_char(sum(readings.reading_diff)::numeric / 1000::numeric
  , 'FM999990.999'::text) AS kwh_per_day
   FROM readings
  WHERE readings.channel = $2 AND readings.rdg_valid 
        AND readings.reading_stamp >= 
        (((SELECT max(readings.reading_stamp) AS max
            FROM readings
            WHERE readings.channel = $2 
                  AND readings.rdg_valid)) - $1::interval) 
        AND readings.reading_stamp <= 
        (( SELECT max(readings.reading_stamp) AS max
           FROM readings
           WHERE readings.channel = $2 AND readings.rdg_valid))
  GROUP BY readings.rdg_date
  ORDER BY readings.rdg_date;$BODY$
  LANGUAGE 'sql' VOLATILE;

Where SELECT * from readings_daily('31 days',0) gives me the same rows of data. Some 15 views per table are replaced by one function. I now just cross-reference those view names with SQL function calls in another table.

 
Posted by jservice at 10:43 PM
February 17, 2005
Ask and ye shall receive

Comments(0) | Print | Home

Watchdog timer board

Regarding that memory leak: I sent an email and called the technical support of the watchdog timer board manufacturer describing the problem. They were kind enough to send me the sources to the DLL and I compiled them. “How about them apples” — no more leaks.

Now I have to make sure that the new DLL is actually setting/resetting the hardware watchdog timer since I had problems trying to link the VC6 LIB file with the Borland C++ code.

 
Posted by jservice at 08:33 PM
February 11, 2005
Too cold for the lithium AA battery

Comments(0) | Print | Home

AA lithium battery

We got a couple of lithium AA batteries as part of a marketing promotion. I used one in our kitchen clock—should be good for a few years. I tried the other in my fm tuner/mp3 player. I have found its output voltage to be very sensitive to the cold. The other day it was in my jacket pocket in about -10°C weather and the device shut off because the battery was too low. When I turned it on later after it warmed up to room temperature the mp3 player said the battery was at full potential. I think I will have to switch back to an alkaline AA battery and use that lithium one for something else.

 
Posted by jservice at 07:54 PM
February 10, 2005
Software plumber

Comments(0) | Print | Home

I was “hired” at work to troubleshoot a problem with some hardware and controlling software running under win2k. There was a memory leak adding 4k to the main process every 10 seconds or so. Using the System Monitor “snap-in” and monitoring the process' “working set” I was able to view the memory leaking away. I traced it to the software (dll?) controlling a hardware reboot timer. After disabling this “feature” the program ran over lunch with nary another byte used. We brought the computer back from the transformer station relay for some remedial work and testing of the software and some other problems it has.

I have always enjoyed software troubleshooting.

 
Posted by jservice at 09:29 PM
January 31, 2005
Remove masking tape immediately after!

Comments(0) | Print | Home

masking tape

I thought this was common knowledge that you removed the masking tape immediately after painting or caulking; otherwise, the coating will dry and stick to the masking tape. A friend at work told me he tried caulking once using masking tape to make clean edges. He let things dry and then found the masking tape pulled up most of the caulking. Another used masking tape to protect the moulding while he painted the walls. Again, he let things dry and then ruined the edge of his paint job. I thought I must share this tip.

 
Posted by jservice at 09:30 PM
January 30, 2005
I just HAD to buy a router table

Comments(0) | Print | Home

Craftsman-router-table-with-extensions.png

My wife is making “Indian” flutes with the Grade 5’s. So far I’ve cut the ½ in PVC pipe to lengths and loaned my two electric drills to make the holes. Soon I’ll have to fabricate little ½ in x 1¼ in pieces to direct the air from one hole to another to give it that “flutey” sound. These parts will require me to use a router table to cut ¼ in grooves in PVC doorstop moulding. As I was at Rona to get the moulding, I looked at the tables and only found generic or mucho-expensive models. As I have had a Craftman router for several years I decided to look for one at Sears just down the road. I ended up buying the medium expensive model shown in the image. You gotta love those marketing images: they show a router table in a workshop with a few shavings but no router. I spent a relaxing half-hour or so assembling the table.

In the not so exciting department I had to replace some of the caulking around the main bathroom’s tub. We are thinking it is time to renovate because of the ugly tub and the bathroom’s rather bland decor. We aren’t sure whether it will be a shower cubicle or a complete bathtub enclosure this time around. I grew up in a house with only a bathtub so I’ve taken showers exclusively ever since I left home. I’m really not into tiling and I think it is difficult to achieve leak-proof results without a lot of skills, time and care. It will be time to look at bathroom furnishings in the next few weeks and start planning.

I’m tired: I increased the distance of my run by several kilometers. Unfortunately snow at about the freezing point starts to lose its hard-pack qualities. The valley trails are starting to become slushy in places. That last third was starting to feel like a real grind.

 
Posted by jservice at 08:44 PM
January 28, 2005
PostgreSQL 8.0 windows port installed

Comments(0) | Print | Home

I took a snapshot of the environment variables on my XP box at work and compared them with the home 2k box. Here was the difference:

ms-dos-icon.png

2k box: COMSPEC=C:\WINDOWS\SYSTEM32\COMMAND.COM!!

XP box: COMSPEC=C:\WINDOWS\SYSTEM32\cmd.exe

When I installed 2000 in place of Me I guess the upgrade kept good ol' COMMAND.COM. I changed this and PostgreSQL installed “perfectly.” I’m not sure why the install used the COMSPEC variable but now I have something else to put on the checklist if an install fails.

I have several thousand hourly readings on each of several channels collected over the last couple of months stored in the database. Now I can use simple SELECT commands to aggregate say the sums of hourly readings/channel for each day or the last 48 hours of readings for a particular channel or the average daily sum of hourly readings/channel/day of the week. Lovely data mining!

 
Posted by jservice at 10:40 PM
January 27, 2005
Native Windows version of PostgreSQL

Comments(0) | Print | Home

postgresql logo

The newest version of PostgreSQL, my “favourite” database now has a “native” Windows port. This couldn’t have come at a better time at work as I need a “big” database for a project I’m involved with. Now I can develop the database on my Windows box and then move it out to the FreeBSD box on the Internet. I certainly couldn’t do that with Access!

Unfortunately it wouldn’t install on my home box because, just near the end, initdb fails and the log reports: creating template1 database in C:/Program Files/PostgreSQL/8.0/data/base/1 … Bad command or file name. I guess I’ll have to compare my home box environment settings to those at work to see what might be is screwing up the installation.

 
Posted by jservice at 09:48 PM
January 24, 2005
rel=“nofollow”

Comments(0) | Print | Home

Looks like I might have to hack up my old copy of Moveable Type again. Google suggests the “major” search engines won’t follow links containing the rel=“nofollow” attribute. This means that comment spammers will no longer have search engines coming to their sites from the junk they post as comments and/or trackback pings on popular blogs. Personally, I have found that using some Apache mod_rewrite rules has eliminated almost all of it.

 
Posted by jservice at 10:01 PM
January 13, 2005
Shorts, MS anti-spyware

Comments(0) | Print | Home

Shorts
With temperatures in the low teens (°C) today I ran home from the train station wearing shorts—a first for a January 13th for me. Unfortunately, like yesterday, it was pouring rain though, unlike yesterday, it wasn’t a thunderstorm. Of course, being winter, tonight’s temperatures will go below freezing and snow is expected.
Anti-Spyware

I tried Microsoft’s beta anti-Spyware software at work and at home yesterday. It seems to be pretty simple-minded about filenames and directories. It found a file, cat.exe, in the system32 directory and called it the Dutch Porn Dialer. Actually it’s a Windows port of the Unix cat command. It also called two expat.dll files spyware. These are an XML parsing library.

I think the software needs more work.

 
Posted by jservice at 10:04 PM
January 10, 2005
Weather in my browser

Comments(0) | Print | Home

Because I walk or run about 6 km each day I like to keep track of the weather. I was planning to web scrape Environment Canada’s website and create an RSS feed for myself. Then I discovered Forecast Fox. Now I can have the weather in the status bar. Neat!

 
Posted by jservice at 09:50 PM
December 30, 2004
Installed a shelf

Comments(0) | Print | Home

zircon-stud-sensor.png

Today I bought a stud finder from the planet Zircon. It used to be a tedious process to find the drywall screws or nails using one of those small pivoting magnet thingys. Of course, now I ask myself why I didn’t buy a “finder” years ago.

I easily located the studs and screwed three standards using a 2 ft level to verticalize and a 4 ft level to horizontalize the brackets. On this hardware I placed a 16 in x 8 ft shelf about 12 in down from the ceiling so my wife can store boxes of stuff “up there” in her sewing room. I also bought a light aluminum step platform so she can reach said boxes.

The greatest part of the time I spent doing this job involved removing the Rubbermaid UPC labels and glue from the six pieces of shelf hardware.

 
Posted by jservice at 10:41 PM
December 17, 2004
AMR Data

Comments(0) | Print | Home

AMR exampleOur company is demonstrating a technique for AMR using the power lines. The novel aspect about this method is that the metering signals can transmit through transformers. Other technologies have to use additional equipment to “go around” those transformers. After a couple of weeks of data gathering for five house within a block of each other there’s some interesting statistics already. The highest energy house uses 4½ times more energy than the lowest one and the peak usage is 3.6 times higher. I’ll have to find out from the test co-ordinator why there’s such a difference: teenagers, electric water heater or heating, extensive outdoor Christmas light display, etc?

 
Posted by jservice at 10:44 PM
December 07, 2004
Array of filehandles in Perl

Comments(4) | Print | Home

# This isn't very explicit on the web so I thought I would show
# a short example of how to make an array of filehandles using
# the IO::File module.

use IO::File ;
my @fh ;

# Make 11 files with the numbers 0 to 10, 1 number per file.
foreach $file (0..10) {
  $fh[$file] = new IO::File ">$file.txt" ;
  # print $fh[$file] "$file\n" ; # This doesn't compile
  print { $fh[$file] } "$file\n" ; # Inside a block it does
}
exit 0 ;
 
Posted by jservice at 09:55 PM
November 25, 2004
Retrieving the Global Address List (GAL) data

Comments(0) | Print | Home

You may recall (or perhaps I neglected to discuss it here) that I was having a problem with the Perl script I used to synchronize our employee email addresses from the LDAP directory to the SQL server database serving our Intranet web site. One early morning it deleted half the names — probably something to do with the domain controller server upgrade to Windows 2003. For some reason the query wasn’t returning all the users in the directory anymore. Part of the problem is that this list of names is also used to establish the Intranet website content managers' permissions. It took me a while to surf through the Google chaff to finally find an article on how to retrieve the information available in the Global Address List of Exchange / Outlook. I culled the vbs script lines and added some of my own changes:

' GEt the domain.
Dim rootDSE, domainObject
Set rootDSE=GetObject("LDAP://RootDSE")
domainContainer = rootDSE.Get("defaultNamingContext")
Set domainObject = GetObject("LDAP://" & domainContainer)
' Create a file for results. 
Set fs = CreateObject ("Scripting.FileSystemObject")
Set userFile = fs.CreateTextFile (".\users.csv")
' Call the sub to do the work.
ExportUsers(domainObject)
Set oDomain = Nothing
MsgBox "Finished"
WScript.Quit

Sub ExportUsers(oObject)
  Dim oUser
  For Each oUser in oObject
    Select Case oUser.Class
      Case "user"
        If oUser.mail <> "" then
          userFile.Write oUser.displayName _
                  & "," & oUser.sAMAccountName _
                  & "," & oUser.userprincipalname _
                  & "," & oUser.sn _
                  & "," & oUser.department _
                  & "," & oUser.physicalDeliveryOfficeName _
                  & "," & oUser.telephoneNumber _
                  & "," & oUser.initials _
                  & "," & oUser.givenName _
                  & "," & oUser.mail
'          for each email in oUser.proxyAddresses
'            userFile.Write email & ","
'          next
          userFile.WriteLine ""
        End if
      Case "organizationalUnit" , "container"
        If UsersinOU (oUser) Then
          ' If users in container call myself again.
          ExportUsers(oUser)
        End if
    End select
  Next
End Sub

Function UsersinOU (oObject)
  ' Are there users in the container?
  Dim oUser
  UsersinOU = False
  for Each oUser in oObject
    Select Case oUser.Class
      Case "organizationalUnit" , "container"
        UsersinOU = UsersinOU(oUser)
      Case "user"
        UsersinOU = True
    End select
  Next
End Function

Then I converted the vbs to a Perl script using the Win32::OLE module:

use Win32::OLE 'in' ;

sub last_error () {
  my $last_error = Win32::OLE->LastError() ;
  die $last_error if $last_error ;
}

sub has_users ($) ;

sub has_users ($) {
  my $object = shift ;
  my $result = 0 ;

  foreach my $user (in $object) {
    if ($user->{Class} =~ /^(organizationalUnit|container)$/) {
      $result = has_users($user) ;
    } elsif ($user->{Class} eq "user") {
      $result = 1 ;
    }
  }
  $result ;
}

sub export_users ($) ;

sub export_users ($) {
  my $object = shift ;

  foreach my $user (in $object) {
    if ($user->{Class} eq "user") {
      if ($user->{mail} ne '') {
        print join(', ', map { "$_: $user->{$_}" } qw[mail displayName]), 
          "\n" ;
      }
    } elsif ($user->{Class} =~ /^(organizationalUnit|container)$/) {
      export_users($user) if has_users($user) ;
    }
  }
}

my $rootDSE = Win32::OLE->GetObject("LDAP://RootDSE") ;
my $domain_container = $rootDSE->Get("defaultNamingContext") ;
my $domain_object = Win32::OLE->GetObject("LDAP://$domain_container") ;
_ddump [$domain_object], [qw[$domain_object]] ;
last_error ;

export_users($domain_object) ;

exit 0 ;

As I’m off to the OMEA conference tomorrow, though I’m not a music teacher, I’ll have to wait until Monday to change my script and restore those missing names.

 
Posted by jservice at 09:42 PM
November 24, 2004
With a little VBA you can automatically save attachments in Outlook

Comments(0) | Print | Home

I have a server which accepts downloads from devices in the field and mails the results to me in an attachment. Outlook doesn’t provide a way to automatically detach and save them. Sometimes you look for stuff using Google and you find a heck a lot of chaff. Finally I discovered how to do this with a short VBA “script.” Outlook XP has a “run a script” action available for its rules but, again, it took a bit of searching to find out how to use it.

Attribute VB_Name = "SaveAttachments"
Option Explicit
' The "run script" check box in the Outlook Rules Wizard looks for subs with
' the Item As Outlook.MailItem argument.
Sub SaveAttachmentMessageRule(Item As Outlook.MailItem)
  ' save_dir must exist.
  Const Save_dir = "c:\attachments\"
  Const process_attachments_program = "C:\Perl\bin\perl.exe C:\bin\got-data.pl"
  Const Ext = "txt"
  Dim Filename As String
  Dim Attach As Attachment
  Dim i As Integer
  
  i = 0
  If Item.UnRead = True Then
    For Each Attach In Item.Attachments
      ' Verify the attachment has the correct extension and is unread.
      If Right(Attach.Filename, 3) = Ext Then
        Filename = Save_dir & Attach.Filename
        Attach.SaveAsFile Filename
        i = i + 1
      End If
    Next Attach
    ' Mark as read.
    Item.UnRead = False
  End If
  Set Attach = Nothing
  If i > 0 Then
    ' Now process the saved attachment(s).
    Shell process_attachments_program
End Sub

Though you can run an application from an Outlook rule it starts before the run a script; hence, I use the Shell command to process the attachment file. Note that you’ll have to change the “Security” settings to enable macros. However, if you know how to use VBA then I would surmise you know how to do this, too.

 
Posted by jservice at 09:33 PM
November 21, 2004
No comment spam to speak of

Comments(0) | Print | Home

In my /etc/hourly.local file I created to update awstats hourly, I added a Perl one-liner to look for comment spam attempts:

perl -ne 'print if /\b(POST|GET)\b/ && /mt-comments\.cgi/ && ! /(mysite|mysisterssite\
)\.com/' /home/myhomedir/logs/blog-access.log

On Nov. 20 there were 212 entries. Not all were comment spam attempts as some 'bots “cruise” the blog looking for open comments. All the rest were stopped with my suggested rewrite rules. It used to be that all those attempts would be clogging the MT activity log with MT-Blacklist comment denial or worse, sending me email about a bogus comment.

 
Posted by jservice at 07:56 PM
November 11, 2004
A quiet MT activity log: no spam for awhile

Comments(0) | Print | Home

Usually there’s dozens of blacklisted spam entries but at lunchtime today I added some mod_rewrite rules per the advice on some other blogs. Everything has been quiet since noon — only my sister and I logging in to our respective blogs. Here’s what I added to the httpd.conf file (change the site and domains to suit):

  # Redirect clients who try to post comments directly.
  RewriteEngine On
  RewriteCond %{REQUEST_METHOD} POST
  RewriteCond %{REQUEST_URI} .mt-comments\.cgi*
  # If the browser did not come from either of ours sites or
  RewriteCond %{HTTP_REFERER} !.*(mysite|mysistersite)\.domain.* [OR]
  # there's no agent.
  RewriteCond %{HTTP_USER_AGENT} ^-$
  # Redirect to an error message page.
  RewriteRule (.*) /no-comment.html [R,L]
 
Posted by jservice at 10:46 PM
November 07, 2004
Three jobs completed in one go

Comments(0) | Print | Home

front walk with topsoil around edges.jpg

The former little garden on the garage side of the walk is starting to fill with leaves giving me an idea. I had a long pile of shredded leaves and pine needles left over in the back behind the deck so I put a layer of this stuff along the edges of the walk from front to back. When I had excavated for the walk, I had piled the topsoil just behind the shrub. This pile provided just enough topsold to spread over the shredded material along the walkway edges. Therefore I used most of the mulch, removed the pile of topsoil and “finished” the sides of the walkway all at the same time. I also saved myself a few bucks by not having to order a cubic yard or two of triple mix for that purpose.

 
Posted by jservice at 10:22 PM
November 05, 2004
New look

Comments(2) | Print | Home

I fiddled around with the colours and fonts on the site. There appears to be some colour “bleeding” with IE. Maybe I’ll fix it when I find an edit css tool like I got for Firefox.

 
Posted by jservice at 10:05 PM
November 04, 2004
favicon.ico changed

Comments(0) | Print | Home

I changed the little thumbnail file: favicon.ico for the hubbo site.

  • I selected an an image of me.
  • Cropped a square section of my portrait and shrunk it to 16×16 pixels using Irfanview.
  • I used the graphic editor in Visual C++ to make the background white.
  • Back in Irfanview I reloaded the ico file and re-saved it making the white background “transparent.”
  • I used the little image for these list item markers.
 
Posted by jservice at 08:34 PM
November 02, 2004
SSH authentication reviewed

Comments(0) | Print | Home

I have a host computer recently installed between between the two firewalls at work in the so-called DMZ. I use ssh to maintain it. It was getting tiresome to type in the password each time I rsync'd some files. It had been awhile since I set up authentication between hosts so a review of the man pages for ssh was called for. I used ssh-keygen -d dsa to generate a public and private key on the client Intranet host. I then appended the contents of ~/.ssh/id_dsa.pub to the file ~/.ssh/authorized_keys2 on the DMZ computer.

 
Posted by jservice at 12:34 PM
October 30, 2004
4 mice

Comments(0) | Print | Home

mouse trap

In the last couple of weeks I have caught four mice in the garage. Now the traps appear undisturbed so perhaps the problem is gone for another year. BTW, I don’t use those clothes peg type traps: they are not as “snappy” as the kind in the image, but you don’t have to touch the dead critter, either.

 
Posted by jservice at 10:03 PM
October 21, 2004
We have an opening

Comments(0) | Print | Home

garage door diagram

After doing some research and talking to other DIYs, I decided to hire someone to replace the torsion springs, one broken and one not, on our single car garage doors. The decision was easier when I found the invoice for the garage doors we had installed in 1990. That company is still in business so I figure they must be doing alright after 14 years. It was less than $250 and done the day after I called. I would still have to measure and buy the springs and then get a couple of tools, etc so it might have been another couple of weeks before I did it myself. Money well spent this time.

 
Posted by jservice at 09:07 PM
October 18, 2004
overlib(mws) added to site

Comments(2) | Print | Home

I installed a javascript package that makes popup overlays on Saturday evening. I used them at work for a demo website with several large (image) maps and selectable houses. I needed little popups to display the house addresses. Through my web research I came across the overlibms package which seemed to be the best of the overlib clones.

It was quite easy to add to an MT blog. I added the following to my various index templates:

<script type="text/javascript" src="http://www.mywebsite.com/include/overlibmws.js"> </script> <script> OLpageDefaults(FGCLASS,"popup_inside",BGCLASS,"popup_outside", TEXTFONTCLASS,"popup_fonts") ; </script>

The second line specifies the styles names used in the popup that are found in your styles-site.css file.

Somewhere, just after the <body> tag, you add:

<div id="overDiv" style="position:absolute;visibility:hidden; z-index:1000;"></div>

This initializes the “floating” div that overlib uses for its little popup box. Of course, I had to add a popup entry title to my calendar entries:

<MTCalendarIfEntries><MTEntries author="me" lastn="1"><a href="<$MTEntryLink$>#<$MTEntryID pad="1"$>" onmouseover="overlib('<$MTEntryTitle$>',WRAP);" onmouseout="nd();"><$MTCalendarDay$></a></MTEntries></MTCalendarIfEntries>

I also lightly hacked the mt/tmpl/cms/preview_entry.tmpl file in a similar fashion so that I can see my popups when I preview my entries. Now I find I might have to revise my TeXlike formatter so that I can embed html in those popups more easily.

 
Posted by jservice at 10:17 PM
October 10, 2004
Walkways all pavered now, torsion spring due diligence

Comments(0) | Print | Home

My wife and I finished laying down the pavers today. My estimates all seemed to have worked out: we have one layer of pavers left over which I can either use to make a step or hide the galvanized sheet I used to cover the opening under the front porch.

I rented a “brick splitter” to do the few cuts needed on the sideway walkway around the downspouts, window well and electrical service entrance. It also came in handy when my wife came to an impasse in the pattern-less pattern. She was using too many of the “twinkie” size. I cut one in half so she could plug up the twinkie run and start a new “twinky-less” pattern.

After using the brick splitter I know more about the sudden release of energy in earthquakes: You apply (enormous) pressure to the paver between two narrow knife-edge blades with a lever arrangement. Usually the paver splits suddenly with a sharp cracking sound and a sudden release in lever force. Another fun part of this job. Tomorrow’s fun includes sawing out a part of the driveway so I can set in the front pavers of the walkway, putting in the edging and sweeping sand in the cracks.

broken torsion spring

The torsion spring broke on the garage door of the side where we keep our car. So, now I am searching the Internet on the subject to determine whether or not this is a DIY project. Apparently it can be with a great deal of care. Perhaps I’ll phone around for repair estimates and time to complete versus the time and expense involved in trying to purchase the spring (not usually available at your typical home repair “supermarket”) and doing it myself.

 
Posted by jservice at 10:45 PM
October 09, 2004
The pattern is ... there is no pattern

Comments(0) | Print | Home

We (yes, my wife helped) laid out a skidful of pavers this afternoon and evening. We had trouble discerning what sort of pattern we should use with these 3 sizes of tumbled pavers: