Wednesday, March 11, 2009

Quick YUI Panel styling sans Javascript

In doing some application mockups, I found a quick way to skin the YUI's Panel widget without having to create Javascript objects to do it for me.

For each panel you need to just add the class yui-panel.

Here is a markup example ( ripped out all but the body stuff out):
<body class="yui-skin-sam">
<div id="doc2" class="yui-t5">
<div id="hd">Header Stuff</div>
<div id="bd">
<div id="yui-main">
<div id="panel1" class="yui-b yui-panel">
<div class="hd">Panel Header</div>
<div class="bd">Here is stuff for the body of the panel</div>
<div class="ft">Panel Footer</div>
</div>
<div id="panel2" class="yui-b yui-panel">
<div class="hd">2nd Panel Header</div>
<div class="bd">Here is stuff for the body of the panel</div>
<div class="ft">Panel Footer</div>
</div>
</div>
<div class="yui-b yui-panel">
<div class="hd">Right Col header</div>
<div class="bd">Body</div>
<div class="ft">Footer</div>
</div>
</div>
<div id="ft"> Page Footer</div>
</div>
</body>
Now I just need to figure what the best way to handle all those div's are... And figure out when to use a block and unit and grid container...

Yikes, I thought YUI was suppose to make my life easier. I need to upload an example, maybe later.

References: Container (Panel is a ), YUI

Easiest way to get SQLite to put in timestamps

After doing some more digging (must have been blind before), I found that SQLite supports a default timestamp at insert.

Here is an example of a create statement using the default with SQLite CURRENT_TIMESTAMP keyword.
create table user (
id integer primary key,
username text not null,
password text not null,
first_name text,
last_name text,
created text default CURRENT_TIMESTAMP
UNIQUE(username)
);
That is much easier that my previous attempt. Not sure how I missed it. But it doesn't solve the missing now() function for updates. ( did find a language solution for that in Perl but that is for another post). In that case, it will still require the use of datetime('now').

Reference: SQLite CREATE TABLE reference.

Tuesday, March 10, 2009

2 ways to get SQLite to put dates into columns

2 ways to get SQLite to put dates into a column.
  1. insert into mytable values( null, datetime('now') );
  2. insert into mytable values( null, strftime('%s', 'now'));
The first one inserts a row somewhat like this:
1|2009-03-10 18:47:46

The second inserts an unix timestamp:
2|1236711411

It might be best to use that unix timestamp with an integer column type for dates since SQLite doesn't support a datetime one.

It makes comparisons and ordering much easier:
select * from dt where lu > strftime('%s', '2009-03-10');

Output of:
id|lu
6|1236643200
2|1236711411
3|1236711516
4|1236711518
5|1236711519
But the formatting is pretty ugly. :-/

Hey what about formatting it within the select with the SQLite datetime function:
select id, datetime(lu, 'unixepoch') lu from dt order by lu;
id|lu
6|2009-03-10 00:00:00
2|2009-03-10 18:56:51
3|2009-03-10 18:58:36
4|2009-03-10 18:58:38
5|2009-03-10 18:58:39
Better but having to add that to each select is kind of a pain. I like adding a new column better:
select *, datetime(lu, 'unixepoch') date from dt order by lu;

Alright done playing now... It would be probably be good to add a language extension for a new function called 'now()'. Some other day :)

For more datetime SQLite information, see the SQLite date reference.

Adding http request/response logging to SOAP::Lite

Sometimes I just want to save the xml versions of the SOAP requests and responses (generally to share with someone else).

The SOAP::Lite perldoc page points to using SOAP::Trace. It has lots of good stuff but its a bit heavy. And in my case, I'm trying to figure out how to log response and requests over http so the following will hopefully help simplify my next search. :)

here is my approach, first the code (all good things start in code :) :
package SOAP::HTTP::Logging;

use warnings;
use strict;

use Exporter;

our @EXPORT = qw(
enable_logging
disable_logging
soap_log_file
log_message
);

our $logfile;
our $logboth = 0;
our $log_request = 0;
our $log_response = 0;

# setup global options
sub enable_logging { $log_request = $log_response = 1; }
sub disable_logging { $log_request = $log_response = 0; }
sub soap_log_file { $logfile = shift if @_; return $logfile; }

# logging sub
sub log_message {
my $in = shift; # SOAP::Lite pushes in the object its called on

# only log configured and enabled
return unless $logfile; # no logfile
return unless ref $in; # only handle objects
return unless $in->can('content'); # object must have content method

# only log if enabled
return unless $log_request or $log_response;

# make logfile more userfriendly
my $pre = "";

# decode prefix
$pre = ( ref $in eq 'HTTP::Request' ? 'Request' :
ref $in eq 'HTTP::Response' ? 'Response' :
'Unknown' );

# open logfile and write out information
open my $fh, '>>', $logfile
or return; ## sliently fail for now

printf $fh "%s [%d] %s: %s\n", scalar localtime, $$,
$pre, ( $in->content ? $in->content : 'N/A' );

close $fh;

## done
return;
}

1;
Well jezz, after copying that all over maybe that would be a good cpan module.

To use it, in the calling code add:
#!/usr/bin/perl

use strict;
use warnings;

use SOAP::HTTP::Logging;
use SOAP::Lite +trace => [
transport => &SOAP::HTTP::Logging::log_message
];

## ... somewhere before doing soap calls ...

# enable library logging
enable_logging();

# where to write log
soap_log_file( 'soap_transport.log' ); # might want a fullpath

# do your soap stuff
my $soap = SOAP::Lite->proxy( 'http://localhost' )->uri( '/Foo/Bar');
my $res = $soap->hi();

# disable logging some reason
disable_logging();

# different request
$res = $soap->login( $username, $password );

# log somewhere else
enable_logging();
soap_log_file( 'new_service_calls.log' );

$res = $soap->account_profile_2(); # a new version of calls

exit;
That's it. I can see several places to improve this code. (like better warnings on failure to open the file, better output formatting (or custom output formatting), xml tidy output, etc...

Wednesday, March 4, 2009

How to confuse ssh

I'm sure there are lots of ways to confuse ssh, just like there lots of ways to confuse me. But this is the one i found.

At work we run Solaris with lots of old tools. I end up building lots of new stuff for my self and then having to work around the old ones. When I worked in a Irix shop, I had to do the same thing but for different reasons.

One of the oddities that I run into is that our login shells are often csh. I like bash or ksh in a pinch. Well this means that I had to hack together a .cshrc that checks for bash and then execs it, leaving me with a perfect world of bash.

It looks something like this:

if ( $_ == "/bin/which" || $_ == "/usr/bin/which" ) then
set which="true"
endif

set BASH = "$PWD/bin/bash"

if ( -x $BASH && $which != "true" ) then
exec $BASH
endif

set BASH = "/usr/bin/bash"

if ( -x $BASH && $which != "true" ) then
exec $BASH
endif
Well ssh does not like this for executing remove commands. When a login shell does that it confuses remove commands but not the remove login one.

For example running: ssh removeserver date would just hang. The debugging output would even say: debug1: Sending command: date then just stop. Unless you add the -t option then it would drop you into a shell.

Very confusing and frustrating, especially when mixed with ProxyCommand and netcat which just does nothing. Or running ssh -t remoteserver ssh nextserver which just drops into a shell on the remoteserver. Then hair pulling occurs :)

I updated to exit before running the bash shell for certain hosts:
if ( `hostname` == 'remoteserver' ) then
exit
endif
Lets just say that it made my afternoon quite unpleasant until I found the solution.