19.12.07
Posted by Jay at 15:48
26.10.07
15.10.07
31.7.07
Super secret decoder ring... in php
It's time for a wee bit of code. The following is a simple php class to encrypt/decrypt strings. This is useful when you need to pass around secret documents but are out of microfiche and fake lipstick tubes.
To use:
<?php
require_once('secretdecoderring.php');
$dr = new SecretDecoderRing();
$enc = $dr->encode($argv[1]);
$dec = $dr->decode($enc);
var_dump($argv[1]);
var_dump($enc);
var_dump($dec);
?>
<?php
class SecretDecoderRing
{
private $key = "supersecret";
private $td;
function __construct()
{
$this->td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->td), MCRYPT_RAND);
mcrypt_generic_init($this->td, $this->key, $iv);
}
function __deconstruct()
{
mcrypt_generic_deinit($this->td);
mcrypt_module_close($this->td);
}
function encode($string)
{
$enc = mcrypt_generic($this->td, $string);
return base64_encode($enc);
}
function decode($string)
{
$enc = base64_decode($string);
$dec = mdecrypt_generic($this->td, $enc);
// It's padded. Really. Security is such a waste of time.
return rtrim($dec, ((ord(substr($dec, strlen($dec)-1, 1)) >= 0 and ord(substr($dec, strlen($dec)-1, 1)) <= 16) ? c
hr(ord(substr($dec, strlen($dec)-1, 1))): null));
}
}
?>
Posted by Jay at 16:29
Labels: decoder ring, php, secret, tripledes
24.7.07
23.7.07
OS X terminal settings for tcsh
Everyone seems to love two features of my OS X environment. Color terminals, and an updating title bar that even works when you ssh. Rock.
Put the following in your .cshrc or .tcshrc file in your home directory.
#
# Terminal stuff
#
setenv TERM "xterm-color"
setenv CLICOLOR "true"
setenv LSCOLORS "exfxcxdxbxegedabagacad"
#
# Auto complete
#
set fignore = (.o \~)
set complete = enhance
#
# Title bar
#
setenv SHORTHOST `echo -n $HOST | sed -e 's%\..*%%'`
alias precmd 'printf "\033]0;%s @ $SHORTHOST\007" "${cwd}" | sed -e "s%$HOME%~%"'
sched +0:00 alias postcmd 'printf "\033]0;%s @ $SHORTHOST\007" "\!#"'
29.6.07
18.6.07
16.5.07
George Bush is a what?
This is video of new friend in Kiev. He is expressing his view of our current administration. I'm not sure where he learned English. :)
Posted by Jay at 11:14
Labels: george bush, Kiev
30.4.07
togo.ebay.com is to interweb as Webster is to...
Ebay is the latest to board the widget band wagon. I think this is a smart move. I mean people love small things right... remember Webster?
slimy liquid marketing
I've spent the last decade listening to the phrase "viral marketing". It seems to be the basis of every tech company business plan and when it works it can make even piece of shit sites like MySpace popular. So, I was sitting in on a marketing meeting today and decided to research the word "viral". The Latin is literally translated to "slimy liquid"... nice.
Therefore, I resolve to called viral marketing "slimy liquid marketing" from this day forward.
hot.
Posted by Jay at 14:12
Labels: viral marketing
27.4.07
lolling chair by thomas moser
Thomas Moser had a sale today so I stopped by on my lunch break. For those not familiar with TM, they have an interesting approach to furniture making. They have really great supplies of wood - especially cherry - and everything is hand assembled. However, all furniture is made in a high tech facility in Maine with big milling machines. This is very close to hand crafted but with a much lower price tag (lower != cheap). So... make sure you hand select what you buy to make sure the grain works with lines of the piece.
Posted by Jay at 14:40
Labels: furniture, modern, thomas moser
25.4.07
pics from Artomatic
A smattering of pics from performances of The Mesmers @ Artomatic.
Posted by Jay at 18:02
Labels: music, pictures, The Mesmers
2.4.07
21.2.07
Shell script to download Google Analytics data
I love Google Analytics. Not only is it visually stunning but it is amazingly flexible given its goal and filtering options. At share2me we use it to gain insight into website usage... and use of the share2me button. This is especially cool because the lightbox (see "share2me launches @ demo") is actually loaded in the current page you are viewing. This means the GA domain report shows the top shared websites. hot.
So far I have only had one problem. There's no GData interface for GA. This means our intern LJ has to spend his morning downloading reports instead of more useful activities, like securing a caffèllatte for Mike. ;)
Anyhoo. I spent a few minutes with Tamper and was able to generate the following shell script. To use:
1. Save the googleanalytics shell script to your computer
2. chmod +x googleanalytics
3. Go to GA and select the website profile you are interested in then copy the report id from the url (?rid=XXX)
3. ./googleanalytics user passwd reportId
This will use the default date range (previous week) and report type (executive overview) and provide output in csv format. I like csv because it is easy to load in R but if you can change x in REPORTURL to x=1 for tab separated and x=7 for xml.
Note: This code is now part of the smorgasbord-o-scripts project.
#!/bin/sh
##########################################################################
# Title : googleanalytics - download Google Analytics data
# Author : Jay Ridgeway <jayridge AT gmail.com>
# Date : 2006-02-20
# Requires : curl
# $Id: googleanalytics,v 1.2 2007/02/21 14:09:26 jayridgeway Exp jayridgeway $
##########################################################################
# Description
#
# Props to 'Felix Geisendörfer aka the_undefined' for defining the type
# codes below. He has a php version available here:
#
# http://www.thinkingphp.org/2006/06/19/google-analytics-php-api-cakephp-model/
#
##########################################################################
PN=`basename "$0"` # program name
VER=`echo '$Revision: 1.2 $' | cut -d' ' -f2`
CURL='curl'
Usage () {
echo "$PN - download Google Analytics data in csv, $VER (jayridge '07)
usage: $PN [-s start] [-e end] [-t type] user passwd rid
Where user is you@gmail.com, passwd is your google passwd, start is start date
of report in YYYYMMDD format, end is end date in YYYYMMDD format, rid is the
profile id of analytics account (visible as rid=<report> when viewing a report
in GA and type is one of thefollowing:
EXECUTIVE_OVERVIEW=2001
CONVERSION_SUMMARY_1=2003
CONVERSION_SUMMARY_2=2108
MARKETING_SUMMARY_1=2004
MARKETING_SUMMARY_2=2102
CONTENT_SUMMARY_1=2005
CONTENT_SUMMARY_2=2202
SITE_OVERLAY_1=2007
SITE_OVERLAY_2=2109
SITE_OVERLAY_3=1312
SITE_OVERLAY_4=1351
MARKETER_OVERVIEW=2101
CPC_PROGRAM_ANALYSIS_1=2103
CPC_PROGRAM_ANALYSIS_2=1220
CPC_VS_ORGANIC_CONVERSION_1=2104
CPC_VS_ORGANIC_CONVERSION_2=1222
OVERALL_KEYWORD_CONVERSION_1=2105
OVERALL_KEYWORD_CONVERSION_2=1221
KEYWORD_CONSIDERATIONS_1=2106
KEYWORD_CONSIDERATIONS_2=1223
CAMPAIGN_CONVERSION_1=2107
CAMPAIGN_CONVERSION_2=1213
DEFINED_FUNNEL_NAVIGATION_1=2110
DEFINED_FUNNEL_NAVIGATION_2=2203
DEFINED_FUNNEL_NAVIGATION_3=1318
ENTRANCE_BOUNCE_RATES_1=2111
ENTRANCE_BOUNCE_RATES_2=2204
ENTRANCE_BOUNCE_RATES_3=1310
WEBMASTER_OVERVIEW=2201
GOAL_TRACKING_1=2205
GOAL_TRACKING_2=1315
CONTENT_BY_TITLES_1=2206
CONTENT_BY_TITLES_2=1306
BROWSER_VERSIONS_1=2207
BROWSER_VERSIONS_2=1321
PLATFORM_VERSIONS_1=2208
PLATFORM_VERSIONS_2=1322
BROWSER_AND_PLATFORM_COMBOS_1=2209
BROWSER_AND_PLATFORM_COMBOS_2=1323
SCREEN_RESOLUTIONS_1=2210
SCREEN_RESOLUTIONS_2=1324
SCREEN_COLORS_1=2211
SCREEN_COLORS_2=1325
LANGUAGES_1=2312
LANGUAGES_2=1326
JAVA_ENABLED_1=2213
JAVA_ENABLED_2=1327
FLASH_VERSION_1=2215
FLASH_VERSION_2=1329
CONNECTION_SPEED_1=2216
CONNECTION_SPEED_2=1330
HOSTNAMES_1=2217
HOSTNAMES_2=1331
DAILY_VISITORS=1201
VISITS_AND_PAGEVIEW_TRACKING=1202
GOAL_CONVERSION_TRACKING=1203
ABSOLUTE_UNIQUE_VISITORS=1204
VISITOR_LOYALTY=1205
VISITOR_RECENCY=1206
NEW_VS_RETURNING=1207
REFERRING_SOURCE_=1208
GEO_LOCATION=1209
GEO_MAP_OVERLAY=1227
NETWORK_LOCATION=1210
LANGUAGE=1211
USER-DEFINED=1212
DOMAINS=1231
SOURCE_CONVERSION=1214
MEDIUM_CONVERSION=1215
REFERRAL_CONVERSION=1216
CAMPAIGN_ROI=1217
SOURCE_ROI=1218
MEDIUM_ROI=1219
OVERALL_AD_A/B_TESTING=1301
SOURCE_SPECIFIC_TESTING_=1302
KEYWORD_SPECIFIC_TESTING=1303
TOP_CONTENT=1304
CONTENT_DRILLDOWN=1305
DYNAMIC_CONTENT=1307
DEPTH_OF_VISIT=1308
LENGTH_OF_VISIT_=1309
TOP_EXIT_POINTS=1311
INITIAL_NAVIGATION=1313
ALL_NAVIGATION=1314
GOAL_CONVERSION=1316
DEFINED_FUNNEL_ABANDONMENT=1317
REVERSE_GOAL_PATH=1319
GOAL_VERIFICATION=1320" >&2
exit 1
}
if [ $# -eq 0 ]; then
Usage
fi
Type=2001 ; # defaults to executive overview
while [ $# -gt 0 ]
do
case "$1" in
-s) Start=$2;;
-t) Type=$2;;
-e) End=$2;;
--) shift; break;;
-h|*) break;;
esac
shift
done
Email=$1
Passwd=$2
Report=$3
if [ ! -n "$Email" ] || [ ! -n "$Passwd" ] || [ ! -n "$Report" ]
then
Usage
fi
COOKIES=${TMPDIR:=/tmp}/cookies$$.tmp
LOGINURL='https://www.google.com/accounts/ServiceLoginBoxAuth'
POST="service=analytics&Email=${Email}&Passwd=${Passwd}&PersistentCookie=yes"
${CURL} -s -c ${COOKIES} -d ${POST} ${LOGINURL} > /dev/null
REPORTURL="https://www.google.com/analytics/home/report"
REPORTURL=${REPORTURL}"?rid=${Report}&vid=${Type}&bd=${Start}&ed=${End}"
REPORTURL=${REPORTURL}"&ss=0&dcomp=0&xd=1&dow=0&dt=3&dtc=2&x=3"
${CURL} -s -b ${COOKIES} ${REPORTURL}
rm ${COOKIES}
Posted by Jay at 09:57
20.2.07
Using jayridge.eda()
I uploaded the R script here:
http://jayridge.googlepages.com/jayridge.eda.R
Now u can use it by sourcing the file from within R. This example shows how to load the function and generates a nonsensical plot from within the R console. ;)
cheers!
source("http://jayridge.googlepages.com/jayridge.eda.R")
jayridge.eda(rnorm(20), "Random Deviates")
Posted by Jay at 14:32
Labels: code, R, statistics
19.2.07
jayridge.eda()
I spent a little time today writing a generic eda function in R. R is way hip but the graphics take a bit of tweaking. My particular problem was that I wanted a small footprint graphic that would give me a good idea of distribution of a univariate data set... that I wouldn't be ashamed of presenting to the executive types. Here is the function:
jayridge.eda<-function(x, title) {
# This function is based on simple.eda from the book,
# "Using R for Introdcutory Statistics", by John Verzani
#
# I found that the general function was useful but needed
# better titling and formatting for use in EDA presentations.
op<-par(no.readonly = TRUE); # save old parameters
par(mai=c(.6,.5,.2,.2))
par(family="sans")
par(cex.lab=1.2)
# Create a layout with two rows. The first row spans
# 3 columns.
#
# [,1] [,2] [,3]
# [1,] 1 1 1
# [2,] 2 3 4
layout(matrix(c(1,1,1,2,3,4), ncol=3, byrow=TRUE), heights=c(1,2))
# Frame 1: print the title, date and
plot.new()
plot.window(xlim=c(0,1), ylim=c(0,1))
title(main=title, cex.main=2)
f<-as.character(summary(x))
fStr<-sprintf("%9s %9s %9s %9s %9s %9s\n%9s %9s %9s %9s %9s %9s",
"Min","1st Qu","Median","Mean","3rd Qu","Max",
f[1],f[2],f[3],f[4],f[5],f[6])
text(0.5,0.5, labels=fStr, cex=1.4, adj=.5, family="mono")
# Frame 2: plot a histogram.
hist(x, main="Histogram", xlab=title, col="orange")
rug(x)
# Frame 3: plot a boxplot.
boxplot(x, varwidth=TRUE, col="orange", border="grey30")
rug(x,side=2)
title("Boxplot")
# Frame 4: plot a normal QQ.
qqnorm(x, col="grey30")
qqline(x,col="red")
par(op); # reset old parameters
}
And here is the fabulous output!
Posted by Jay at 18:37
Labels: code, R, statistics
13.2.07
Segmented Barplot using R
I've started working on an Exploratory Data Analysis (EDA) for share2me, now that real live folk (as opposed to us tech weenies) are sharing stuff. Naturally, being a statistician at heart I went straight to http://www.r-project.org/ to download the latest rev of R.
My first goal was simply to get back on the bike and start pedaling. In stats this amounts to some judicious select statements and data loading (statistics doesn't have the same issue shortening the name as fraternities). Then typing two lines of code:
x<-read.csv("~/R/data/inconspicuous.csv", header=F)
barplot(table(x[,1],x[,3]), main="Inconspicuous Segmented Barplot", col=rainbow(20,start=.1,end=.8), axisnames=F)
results in the following fabulously segmented barplot... totally bitchen!
Posted by Jay at 18:10
Labels: barplot, R, statistics
12.2.07
Mike's got style
Check out the groovy Kenneth Coles that Mike Blackwell (CEO Nextumi, Inc) wore at the demo.com conference. I'm more of a Fluevog fan, but I gotta admit those are some hot shoes!
Posted by Jay at 10:22
Labels: fluevog, kenneth cole, shoes
8.2.07
WOW is right ;)
7.2.07
Zend and Google calendar
So I've been spending a few days since launch reviewing the operational, product and marketing metrics for share2me. We have a 10 minute morning call @ 10 minutes before 10am every day where I update the team on basic metrics such as # of registrations and hot sources of traffic. So I started to think what a good idea it would be to put that data in a calendar that the team could subscribe to... so I don't have to consume any of the precious few 10-b4-10 minutes. After a quick search I found a fabulous (if not a tad on the undocumented) library provided by the Zend team.
Here's the basic code to post to a calendar.
<?php
require_once 'Zend/Gdata.php';
require_once 'Zend/Http/Client.php';
require_once 'Zend/Gdata/ClientLogin.php';
require_once 'Zend/Gdata/Calendar.php';
$email = 'YOU@gmail.com';
$passwd = 'PASSWD';
$feedUrl = 'http://www.google.com/calendar/feeds/BLAH';
$client = Zend_Gdata_ClientLogin::getHttpClient($email, $passwd, 'cl');
$cal = new Zend_Gdata_Calendar($client);
$timestamp = time();
$start=date('Y-m-d', $timestamp);
$end=date('Y-m-d', ($timestamp + (60 * 60 * 24)));
$xmlString = <<<XML
<entry xmlns='http://www.w3.org/2005/Atom'
xmlns:gd='http://schemas.google.com/g/2005'>
<category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/g/2005#event'></category>
<title type='text'>Title for my event</title>
<content type='text'>This is where all the content goes.</content>
<author>
<name>Jay Ridgeway</name>
<email>YOU@gmail.com</email>
</author>
<gd:transparency value='http://schemas.google.com/g/2005#event.transparent'/>
<gd:when startTime='$start' endTime='$end'/>
</entry>
XML;
$xml = new SimpleXMLElement($xmlString);
$cal->post($xml->asXML(), $feedUrl);
?>
6.2.07
share2me launches @ demo
Dig it, after a few months of painstaking product definition and a lot of work reviewing the capabilities of different communication networks, share2me launches not just a product but a company @ demo.com conference. This is a very interesting product. The tag line is "share anything. to anyone. anywhere" and thats pretty much spot on.
From a technical perspective, the major components are:
1) The browser button. This is just a simple Firefox plugin that executes a javascript url instantiating the lightbox below.
2) The lightbox. This is the visual framework for the product. It is generated using the now fairly common javascript injection technique. This enables us to grab interesting data directly from the dom of the page you are viewing.
3) The clippers. These are site specific DOM inspectors that can grab relevant information from a variety of different sources... like videos from youtube or pics from facebook.
4) The mashed up address book. You didn't think you would have to type in all those addresses manually did you? All the common web email clients are supported as well as some unexpected sources like MySpace and AIM.
5) The sharebox. This is a history of shared messages with more details... like delivery status.
6) The communication switchboard. This is the fun part. We actually send the message as a:
- MySpace comment
- MySpace message
- MySpace profile post (about me section)
- AIM
- SMS