Using an iPhone and a Mac Mini as a baby monitor

Posted in Uncategorized with tags , , , , , , , , on July 20, 2011 by skeldoy

Having recently misplaced the proper baby call, we needed a new way of checking if the baby is really sleeping. At first we used an iPhone app called BabyMonitor – and ran it on an iPad1 while listening on one of our iPhones. The system is very reliant on Wifi and can be quite unstable. And event on your phone will trigger a drop in the application and you then need to pair them up again before it works properly.

The solution was not elegant enough. I then started experimenting with different setups. On the Mac Mini I hooked up an external web cam and made the audio input come from the web cam – on a usb-extention cord to the baby’s room. I then tried 3 things. First I did a Quicktime Stream server and used the QuickTime Broadcaster application on the Mac Mini to create a stream. This approach – though it would scale well didn’t really match up well on the iPhone or the iPad as a client – without writing a html-page and embedding the stream in that page. Scrapped that plan. Then I went for FaceTime. Using FaceTime I had video and sound directly between either an iPad or the iPhones. Excellent. One drawback was that the video-part of it made the iPhone very hot – and it drained battery very fast. An added problem was the same as on the BabyMonitor-app – it needs wifi to work – any drop in connectivity means that you need to place a new call and answer that call in the other end. Scrap that.

The last and final solution – so far – is to run Skype on the Mac Mini – create a special account that auto answers people you have in your contact list. You then use the Skype-app on the iPhone to call in to the baby-monitor-account. This was you instantly get audio when dialing in – you can even go video – but that is not needed. The system works quite well – it’s even available on the 3G network – so the wifi-connectivity-issues aren’t important. Having an unlimited data-plan – I have no scruples doing it entirely over 3G on the iPhone-side – and the quality of the audio is not bad at all.

So if you already own a machine – any kind – be it linux, pc, mac or whatever – and already own an external webcam – already own the usb-extention cable and a smartphone or tablet capable of running skype – this solution is free. Skype doesn’t cost a dime – and the only thing you need to worry about is paying for the data – unless you go unlimited. You can even do an iPad->iPhone, iPad->iPad, iPhone->iPhone, Android->iPhone,Galaxy->iPad. The sky is the limit in terms of platforms – but a real cheap old linux-box would suffice.

Different uses – different platforms

Posted in Uncategorized with tags , , , , , , , , on March 22, 2011 by skeldoy

Lately I’ve started to notice how far behind Microsoft is getting in terms of usability, performance, stability and ingenuity. It is time it died in the personal computing business and in corporate IT. With the advent of the iPhone, iPad, Android it is clear that Microsoft will have no place in most regular peoples lives in the decades to come. Most people now jump ship and go straight for the Mac for a hassle free day-to-day computing experience. But in corporate IT the Mac isn’t really the tool for the job. Even though I love the Macs at home – it’s clear to me – given my job in corporate IT that the person-centric Mac-culture is far from ideal in the fascistic corporate environment. This is where Linux comes in. Far from being the easiest platform for the end user – Linux is still the most customizable platform on the planet. It has all of the features that modern Microsoft-products are missing at the moment. It’s easy to use, fast, stable and is the most advanced kernel on the planet. The OSS culture is also the most resilient and shows that it is ahead of it’s time in ingenuity, security and usability given the recent advent of the Mac-AppStore on the Mac-platform. It’s time for Microsoft to die and the market to split into two segments: Private – using Apple-products and slowly shifting to Android. Corporate – using Linux/OSS right from the get-go: Harvesting productivity gains, security increases and stability benefits that will take us right back to the time of the UNIX.

Benchmarking simple stuff in different languages

Posted in linux, perl, programming on July 29, 2010 by skeldoy

I wanted to find out just how big the differences in speed was between popular languages. To benchmark the languages I choose a very simple but common operation to be performed in similar conditions with different languages. The results came as quite a surprise.

Method

To do this benchmark I made simple Hello World programs in the different languages (some compiled, some interpreted). I then wrote a simple wrapper in Perl that ran the programs in a for-loop, simulating running the program 1000 times. This method may be a testament to how well my ubuntu fires different executables and frameworks and not to the code, but it is still interesting to see how a real world application of a program language is to do a menial task like printing a string many times. To eliminate the graphics-card I piped the output of the programs to a file in one instance and did nothing with it in another instance (just back-ticking the output to a perl-variable and then doing nothing to it). Before claiming that the methodology is unfair I would like to point out that this is the way I run programs on linux/unix and that for my particular use this is  a valid benchmark.

Language Seconds
Asm (nasm) 0.46
C (llvm) 0.84
Obj-C (llvm) 0.85
C (gcc) 0.87
Sh 1.11
C++ (llvm) 1.22
Pascal (fp) 1.48
Awk 1.83
C++ (gcc) 1.86
Fortran (G95) 2.15
Brainfuck 2.24
Perl 3.01
Bash 3.13
Cobol (open) 3.35
Obfuscated Perl 3.68
Ruby 5.35
Tcl 5.53
Python 16.33
Php 103.97
Java 121.88
Groovy 1318

Doing another benchmark where I basically let the hello world program contain a 1000000 long for-loop written in the program itself and then running this program 10 times I got different results:

GCC:    timethis 10:  1 wallclock secs ( 0.00 usr  0.00 sys +  0.69 cusr  0.39 csys =  1.08 CPU) @  9.26/s (n=10)
LLVM:    timethis 10:  1 wallclock secs ( 0.00 usr  0.00 sys +  0.68 cusr  0.42 csys =  1.10 CPU) @  9.09/s (n=10)
Perl:    timethis 10:  2 wallclock secs ( 0.00 usr  0.00 sys +  1.73 cusr  0.44 csys =  2.17 CPU) @  4.61/s (n=10)
Python:    timethis 10:  8 wallclock secs ( 0.00 usr  0.00 sys +  6.41 cusr  0.68 csys =  7.09 CPU) @  1.41/s (n=10)
Php:    timethis 10: 40 wallclock secs ( 0.00 usr  0.00 sys +  7.20 cusr 28.15 csys = 35.35 CPU) @  0.28/s (n=10)
Java:    timethis 10: 111 wallclock secs ( 0.00 usr  0.01 sys + 36.21 cusr 61.36 csys = 97.58 CPU) @  0.10/s (n=10)
Bash:    timethis 10: 321 wallclock secs ( 0.00 usr  0.01 sys + 248.54 cusr 49.48 csys = 298.03 CPU) @  0.03/s (n=10)

This speaks to the sluggishness of the different interpreters and virtual machines and/or the size of the executable. But it also underlines the importance of choosing which programming language you use wisely depending on the case you want to solve. Sure this is a moot point in most cases, but imaging taking development time into account. Writing something in PHP can be OK to solve a problem quickly, but seeing that writing the same code in Perl can be as easy or even easier and seeing the performance boost that script would have makes you wonder why PHP is even out there.

The most surprising result is the Bash. Running a simple bash-script 1000 times from the console is pretty snappy in terms of other scripting languages, but having bash loop a million times and running that is slower than even Java. That is a real surprise. The relative slowness of Python is also interesting, given that Python’s popularity is growing where Perl looses supporters. But equally as surprising is the speed at which Perl does this simple operation. Writing stuff in Perl is relatively straight forward (compared to C) but that does not seem to be a problem when doing menial tasks like this.

Language Seconds
Asm (nasm) 0.46
C (llvm) 0.84
Obj-C (llvm) 0.85
C (gcc) 0.87
Sh 1.11
C++ (llvm) 1.22
Pascal (fp) 1.48
Awk 1.83
C++ (gcc) 1.86
Fortran (G95) 2.15
Brainfuck 2.24
Perl 3.01
Bash 3.13
Cobol (open) 3.35
Obfuscated Perl 3.68
Ruby 5.35
Tcl 5.53
Python 16.33
Php 103.97
Java 121.88
Groovy 1318

Converting images between formats

Posted in linux, macosx, perl on July 20, 2010 by skeldoy

I wanted to convert a bitmap (.bmp) image to an ascii art here the other day.

I did ls /usr/bin/*toascii and found a program to convert from pbm to ascii (pbmtoascii) from the netpbm package. That was swell. So I did another ls /usr/bin/*topbm to find a way of doing a .pbm image. I got a list of programs but alas no bmptopbm.

So after contemplating usage of the many online ascii art generators I decided to do the least cost effective thing and write a program to determine possible conversion paths from one format to another using the netpbm and other packages out there.

I tried writing a recursive function that looked for converters until all of them would be found, but due to the nature of the netpbm-package some image-formats are only convertible to one other format and some are convertible to multiple formats. That meant that I have a lot pitfalls in terms of writing a good recursive function to find all of them. Multiple loops to get stuck in. So I gave the job to my CPU and decided to not spend my time scratching my head for a recursive routine. In stead I would map out all the converters in a couple of layers in both directions and use Dijkstra or some other graph-traversing algorithm to find the way to go.

#!/usr/bin/perl
use Graph;
my $g = Graph->new;
$input = $ARGV[0];
$output = $ARGV[1];
$g->add_vertex($input);
$g->add_vertex($output);
my @toOutput = &findTo($output);
foreach my $format ( @toOutput) {
$g->add_vertex($format);
$g->add_path($format,$output);
my @levelTwo = &findTo($format);
foreach my $forma (@levelTwo) {
$g->add_vertex($forma);
$g->add_path($forma,$format);

and so on and so forth. And thus be able to do:

print “Graph: $g \n”;
@path = $g->SP_Dijkstra($input,$output); if (!@path) { print “No path\n”; }
else { print “Dijkstra-Path: @path \n”; }

And that would yield, when running for instance find bmp ascii:

Dijkstra-Path: bmp ppm pgm pbm ascii

And thus I found a way of converting a .bmp to a .ppm and convert the .ppm to a .pgm to be converted to a .pbm and lastly from .pbm to .ascii. Adding a couple of lines to map the graph point that is the mighty ImageMagick convert tool I can then convert from jpeg to ascii doing the extra step from jpeg to bmp.

So if anybody wonders … for instance how to convert a .st4-file to .tiff here’s the solution:
st4 to pgm, pgm to pbm, pbm to gem, gem to pnm, pnm to tiff…

Or maybe you are wondering how to convert a PostScript file to ascii in a completely useless way? :
ps to pnm, pnm to jpeg, jpeg to bmp, bmp to ppm, ppm to pgm, pgm to pbm, pbm to ascii

Simple networking with Java

Posted in Uncategorized with tags , , , on April 20, 2009 by skeldoy

Here is a simple way of finding out if a port on a host is open. Nice code to have laying around if you work in an environment with lots of different types of systems.

import java.net.*;import java.io.*;import java.util.*;

public class whatEver {

static void singleSocketOpen (String hostname, int socket) {

try { Socket s = new Socket(hostname, socket); s.close();

System.out.println(“Port “+socket+”, “+ portInfo(socket) +” on “+hostname + ” is open.”); }

catch (UnknownHostException e) {System.out.println(“no such host”);}

catch (IOException ioe) {System.out.println(“port closed.”);}

} }

iPhone development – a summer breeze on a hot platform

Posted in Uncategorized with tags , , , , , , , , , on January 28, 2009 by skeldoy

I just started iPhone development three days ago. When I begun I had zero knowledge of Objective C and/or the iPhone APIs as a whole. The only programming experience I have is with Perl, bash, some Java, some Tcl/TK and some pretty rough knowledge of C.

The first day I did the obligatory “Hello World”-stuff and made an app with a couple of buttons that updated text on the view. Pretty straight forward if you just follow a tutorial. The XCode-environment, fancy as it is, can be a little daunting, so I decided to do the classic learning by doing and see how far I got.

Day two was spent with Interface builder and XCode to draft a rough sketch of my app and then link the stuff together with XCode, building the interfaces and synthesizing them in my code to play with them. After one hour of playing I found that I already had half my app there, so I spent the rest of the day looking up the different APIs that I needed to make my app. This went surprisingly fast. I was anticipating, with my complete lack of Objective-C experience, a couple of days work of trial and error to just piece together a running thing. To my great surprise, not only did I get it running on day two (my app) but I had managed to make it run with zero memory leaks or warnings from the compiler. At the end of day two I felt so confident that I applied for the iPhone developer program to get my app on my device.

Day three started at two in the morning, just hours after I had put in my request to join the developer program. After an hour or so of emails and web-forms I had my app running natively on my device. After gearing down with a beer I went to sleep, eagerly anticipating the next day of coding. When I got up I realized that I actually had managed to create a native iPhone app in two days and deploy it on my device by day three. All the stuff I had heard about the program just seemed like pure nonsense in light of how breezy it all went for me. 

Now I am at the end of day three. The day has been spent creating new graphics for the app and tuning some of the off-device code that the device will communicate with on the outside to accomplish the mission. If anyone asks me I will gladly recommend the program for anyone who loves the iPhone and has a couple of hours to create something they want.  

Just my two cents but I seriously believe you have to have the Microsoft-company pretty far up your ass to complain about the iPhone developer program, the decisions they make and the speed at which you are expedited. Think about it. There are tens of thousands of iPhone developers and tens of thousands of apps and still they manage to have some degree of control over what you can sell at their store. Without enforcing some kind of control over the content that they sell they would basically encourage people to scam folks for dough by falsely marketing their apps. I for one welcome our fruit-based overlords. :)

Changing the text on the display of a HP-printer using Perl

Posted in Uncategorized with tags , , , , , on January 12, 2009 by skeldoy

Use this script to change the text on the display of your HP-printer. You can of course pair it with a port-scanner and change every display in your organization (if that floats your goat). :)

#!/usr/bin/perl -w

use IO::Socket;

unless ($ARGV[0]) { die “Use: command IP.AD.RE.SS STRING”; }

$ip = $ARGV[0]; $text = $ARGV[1];

my $sock = new IO::Socket::INET (

PeerAddr => $ip,

PeerPort => ’9100′,

Proto => ‘tcp’,

);

die “No socket!” unless $sock;

print $sock “\e%-12345X\@PJL RDYMSG DISPLAY = \”$text\”\n”;

print $sock “\e%-12345X\n”;

close ($sock);

Alerting about new mail on exchange server using bash

Posted in Uncategorized with tags , , , , , , , on January 12, 2009 by skeldoy

I am the sole linux user at my office. The other folks use the exchange-client available on their windows-installations. I refuse to use it, so I use the webmail-client. The problem with the webmail is that you have to log on to see whether you’ve got new mail. I did this script to check it for me, and I pull it in a timed loop so it checks every ten minutes or so. I even have it playing on the pc-speaker to announce new mail.

Have fun! Remember to fill in the required variables! :)

#!/bin/sh

wget –user=USERNAME –password=PASSWORD https://webmail.YOURDOMAIN.WHERE/exchange/EMAIL.ADDRESS/Inbox/?Cmd=contents -O inbox –quiet

MAILCOUNT= `cat inbox | grep -i -o “icon-msg-unread.gif”|wc -l`

echo -n “You have “;

if [ $MAILCOUNT != 0 ]; then

echo “$MAILCOUNT new message(s)”

else

echo “no new messages”

fi

rm inbox

Splitting input with bash

Posted in Uncategorized with tags on January 12, 2009 by skeldoy

#!/bin/bash
input=$1
key=${input%:*}
value=${input#*:}
echo $key
echo $value

Dirty hack for viewing sun rise/set data from yr.no

Posted in Uncategorized with tags , , , , , , , , , , , , , , on January 2, 2009 by skeldoy

Ever wondered how many hours of sun light you get during each month of the year? With this quick/dirty perl-hack, you can pull data from the Norwegian Meteorological Institutes astute web-site and see for your self with the google chart APIs. All you need is perl, XML::Simple and LWP::Simple. In this example I use my own location (Oslo, Norway). All you need to do to modify it is to find out your latitude and longitude. I have set it up to fire a safari-window with the url by using the “open”-statement. You may want to change that to something else.

sunData.pl:

#!/usr/bin/perl -w

use XML::Simple;# qw(:strict);

use Data::Dumper;

use LWP::Simple;

$location = “lat=59.57;lon=10.42″;

for (my $month = 1;$month<13;$month++) {

for (my $date = 1;$date<31;$date++) {

$mon = sprintf(“%02d”,$month);

$dat = sprintf(“%02d”,$date);

$url = “http://api.yr.no/weatherapi/sunrise/0.9/?$location;date=2009-$mon-$dat”;

$content = get(“$url”);

if ($content ne “”) {

my $parser = XML::Simple->new(); 

$sunData = $parser->XMLin(“$content”);

push (@sunRisings, $sunData->{time}->{location}->{sun}->{rise});

push (@sunSettings, $sunData->{time}->{location}->{sun}->{set});

}

}


for (my $i = 0; $i <= $#sunRisings; $i++){

my $riseTime = substr $sunRisings[$i], 11, 8;

my $setTime = substr $sunSettings[$i], 11, 8;

my $riseHour = substr $riseTime, 0,2;

my $setHour = substr $setTime,0,2;

my $hoursOfLight = int ((($setHour – $riseHour)/24)*100);

push (@lightArray, $hoursOfLight);

}

$urlThang = join (‘,’ , @lightArray);

$chartLink = “http://chart.apis.google.com/chart?
cht=lc&chd=t:$urlThang&chs=800×300&chco=4D89F9&
chxt=x,y&chxr=0,30,356&chm=o,0066FF,0,-30.0,6&chg=30,5,1,0″;

chomp($chartLink);

`open “$chartLink”`;

Playing some low-fi drums on your PC-speaker

Posted in Uncategorized with tags , , , , , , , , on December 31, 2008 by skeldoy

If you’re like me, and loooves the 0LdSCH00l low-fi stuff, you are probably aching to experiment with the PC-speaker under linux. I do not actually own a machine with a PC-speaker, but I have access to one where I work, so one day I got together some code and started playing. The code is by no means elegant (it is a pretty cut-n-paste project) but I have tried laying it out in a pretty pedagogic fashion.  The main thing here is that we want to set up some basics for making some noise. 

You compile it regularly with gcc or your other favourite tool. And yeah. It’s C-code for the Linux-platform, but may compile under *BSD as well (not mac os x though).

music.c:

#include <fcntl.h>

#include <getopt.h>

#include <signal.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/ioctl.h>

#include <sys/types.h>

#include <linux/kd.h>

#ifndef CLOCK_TICK_RATE

#define CLOCK_TICK_RATE 1193180

#endif

int console_fd = -1;

typedef struct beep_parms_t {

  float freq;     

  int length;       

  int reps;       

  int delay;      

  int end_delay;  

  int stdin_beep; } beep_parms_t;

void handle_signal(int signum) {

  switch(signum) {

  case SIGINT:

    if(console_fd >= 0) {

      ioctl(console_fd, KIOCSOUND, 0);

      close(console_fd);

      exit(signum);

    } else {

      /* Just quit gracefully */

      exit(signum);

    }

  }

}

void play_beep(beep_parms_t parms) {

  int i;

  if((console_fd = open(“/dev/console”, O_WRONLY)) == -1) {

    fprintf(stderr, “Run as root/sudo\n”);

    perror(“open”);

    exit(1);

  }

  /* Beep */

  for (i = 0; i < parms.reps; i++) {                    /* start beep */

    if(ioctl(console_fd, KIOCSOUND, (int)(CLOCK_TICK_RATE/parms.freq)) < 0) {

      perror(“ioctl”);

    }

    usleep(1000*parms.length);                          /* wait…    */

    ioctl(console_fd, KIOCSOUND, 0);                    /* stop beep  */

    if(parms.end_delay || (i+1 < parms.reps))

       usleep(1000*parms.delay);                        /* wait…    */

  }                                                     /* repeat.    */

  close(console_fd);

}


void playIt (float freq) {

 int len = 30;

  char sin[4096], *ptr;

  beep_parms_t *parms = (beep_parms_t *)malloc(sizeof(beep_parms_t));

  parms->freq = freq; parms->length = len;parms->reps=40;parms->delay = 0.1;

  parms->end_delay  = 0; parms->stdin_beep = 2; signal(SIGINT, handle_signal);

  play_beep(*parms); free(parms);

}

void playUt (float freq) {

 int len = 8;

  char sin[4096], *ptr;

  beep_parms_t *parms = (beep_parms_t *)malloc(sizeof(beep_parms_t));

  parms->freq = freq; parms->length = len;parms->reps=1;parms->delay =40;

  parms->end_delay  = 40; parms->stdin_beep = 2; signal(SIGINT, handle_signal);

  play_beep(*parms); free(parms); /* printf(” %f \n”, freq); */

}

Then all we need to do is define some sounds:

void bass () { playUt(130.813); }

void snare () { playUt(523.252); }

void hh () { playUt(4186.016); }

void not () { playUt(2); }

void bass2() { playUt(110); }

void snare2 () { playUt(440); }

void hh2 () { playUt(3520); }

And create some beats:

void beat () {

bass();not();

hh();not();

snare();not();

hh();not();

bass();not();

hh();not();

snare();not();

hh();not();

}


void beat2 () {

bass2();not();

hh2();not();

snare2();not();

hh2();not();

bass2();not();

hh2();not();

snare2();not();

hh2();not();

}

And then we play:
int main(int argc, char **argv) {

signal(SIGINT, handle_signal);

beat();beat();beat2();beat2();beat();beat();beat2();beat2();

  return 0; }

You can of course experiment all you want here, to make the perfect oldschool tune. It is worth noting that you can’t really access your speaker without being root or sudo‘ing it. Have fun! :)

Google chart APIs

Posted in Uncategorized with tags , , , , , on December 30, 2008 by skeldoy

Creating charts with the google apis are pretty simple. You just feed parameters to the api and you get some pretty graphs, pie charts, venn-diagrams, maps and other stuff back. Watch the URLs in the examples to see what we need to do. All the charts have a couple of basic parameters. chs indicates the size of the chart. cht indicates the type of chart we want to draw. You can draw a lot of different types of charts but I will only give you three examples.

To make a pie-chart. You specify percentages with the chd=t:X,Y,Z parameters. The chl-parameter is used to nominate the different slices of the pie:
http://chart.apis.google.com/chart?cht=p3&chd=t:10,30,20,40&chs=450×200&chl=the|state|of|things

To make a Venn-diagram you just specify the size of the different sets with the chd=t:X,Y,Z followed by the overlap of the different sets XY,YZ,XZ: 
http://chart.apis.google.com/chart?cht=v&chd=t:70,70,70,30,30,30&chs=450×300

To draw a map you specify the cht (chart-type) t and give the “strength” of colours with the chd-parameter. The chtm-parameter defines the map you want (world, europe, america, africa, asia, etc) while the cocd sets the colour-codes of the colouring. chld takes (ISO) country-codes of the countries you want to highlight:

http://chart.apis.google.com/chart?cht=t&chs=440×220&chd=t:100,50,0,25,75,30,60,90,50,90,80,70,20,10,50,70,60,50,0&chtm=europe&cocd=FFFFFF,EFFEEE,FFAAAA&chld=NOSEDKGBFRHURUESITDENLBEFILUROGRCYCZMC

Read more on the google chart-api here

iTunes and external drives

Posted in Uncategorized with tags , , , , on December 29, 2008 by skeldoy

Seems there is an issue with using iTunes in combination with external drives. It seems to be the case that iTunes probes your drives on start and never tries to probe them again to see if they became writable. I got a really funky error message saying “You do not have the privilege to make changes” when trying to rip my jole-presents. After quitting iTunes and remounting the external drive (where my Library is located) it started working again.

Table sizes and modern browsers

Posted in Uncategorized with tags , , , , , , , on December 28, 2008 by skeldoy

Working on a project recently I discovered that modern browsers (well all browsers really) have a really suboptimal way of rendering HTML-<table>s. A (pretty big (16000*7 entries)) table that takes 1.5 seconds to download may take a couple of minutes to render in all the browsers I know people in my organization use. Mozilla Firefox, Internet Explorer, Opera, Safari – the works. 

One solution is to draw <div>-fields and fill them with data separated by <br>-tags – that solution is as ugly as it is weird. Another solution that I have heard about is to do css-work to customize the layout of the div-work. Not really sure how that would be faster. Nicer, not faster.. Well it goes something like this:

  <div class="row">
    <div class="column">DATA</div>
    <div class="column">DATA</div>
  </div>
 .row { display: table-row; }
 .column {   display: table-cell; border: none; }

… But all this seems pretty hackity-hack for my taste. 

Does anyone have any suggestions for speeding up table-rendering? Why is this broken? Is it something to do with html not having a predictable size? Is there a way of declaring sizes of tables beforehand so that the browsers handles this? More questions than answers…

Reading CSV-files and posting them to a MySQL-database with Perl

Posted in Uncategorized with tags , , , on December 28, 2008 by skeldoy

I recently came over a situation where a lot of csv-files needed to be parsed and posted to a database to enable web-interfacing. The SQL-function for loading csv-files didn’t really float the boat and we needed stronger control over how stuff was done. The solution became csv2html and this is the first part. csv2mysql.pl:

#!/opt/local/bin/perl # you may need to change this
####################################################
# CSV to MySQL-parser. Sverre Eldøy (skeldoy@gmail.com)
####################################################
$|=1;
use DBI;
use POSIX qw(locale_h);
if (!$ARGV[0]) {die "** No filename specified!\n 
Use with ./csv2mysql NAMEOF.CSV\n"; }
# This is the configuration for your mysql-database
$hostname="localhost";     # where is the database?
$username="root";          # name of the account
$password="";              # account-password
$defaultDatabase = "test"; # We assume that there 
# is a database called test to generate dB


$databasename="csvData";   # Name of the database we wanna build.
$DEBUG=0;
$table = "csvData";
if ($DEBUG) {
	print "Creating database $databasename \n";}
my $createDB = DBI->connect("dbi:mysql:$defaultDatabase;$hostname"
,$username,$password);
my $createDBquery = "CREATE DATABASE IF NOT EXISTS $databasename";
my $createDBbuildConnection= $createDB->prepare($createDBquery);
$createDBbuildConnection->execute();
$createDBbuildConnection->finish();
if ($DEBUG) {
	print "Parsing file $ARGV[0]:";}
$entryCount = `cat $ARGV[0]|wc -l`;
chomp($entryCount);
$fieldCount=0;
if ($DEBUG) {
	print "$entryCount entries in csv\n"; }
open (CSV,"<$ARGV[0]");
while (<CSV>) {
	@line = split (';',$_);
		if ($#line>$fieldCount){
			$fieldCount=$#line;} }
close CSV;
if ($DEBUG) {
	print "Guessing there will be a $fieldCount field 
table with $entryCount entries\n"; }
my $createTable = DBI->connect("dbi:mysql:$databasename;$hostname",
$username,$password);
my $dropTableQuery = "DROP TABLE $table";
my $dropTableConnection=$createTable->prepare($dropTableQuery);
$dropTableConnection->execute();
$dropTableConnection->finish();
push (@TableQuery,"CREATE TABLE IF NOT EXISTS 
$table(id INT NOT NULL AUTO_INCREMENT");
for (my $i=0;$i<($fieldCount+1);$i++) {
	push(@TableQuery,"csvvalue$i TINYTEXT"); }
push (@TableQuery,"PRIMARY KEY(id))");
$createTableQuery=join(",",@TableQuery);
if ($DEBUG) {
	print "CreateTableQuery:$createTableQuery\n";}
my $createTableConnection=$createTable->prepare($createTableQuery);
$createTableConnection->execute();
$createTableConnection->finish();
open (CSV,"<$ARGV[0]");
while (<CSV>) {
	chomp($_);
	$_ =~ s/\"//g;
	my @line = split (';',$_);
	my $lengthToken=$#line+1;
	my @insertQuery;
	my $insertTableQuery;
	push (@insertQuery, "INSERT INTO 
$table VALUES (NULL,\"$line[0]\"");
	for (my $j=1;$j<($lengthToken);$j++) {
		push (@insertQuery, ",\"$line[$j]\""); }
	while ($lengthToken<($fieldCount+1)) {
		push (@insertQuery,",NULL");$lengthToken++;  }
	push (@insertQuery,')');
	my $insertTableQuery = join ("",@insertQuery);
	if ($DEBUG) {
		print "$insertTableQuery\n"; }
	$insertConnection = $createTable->prepare($insertTableQuery);
	$insertConnection->execute();
	$insertConnection->finish();
}
close CSV;

Trimming a linux-distro with Perl and ldd

Posted in Uncategorized with tags , , , , , , on December 28, 2008 by skeldoy

When working on a linux-OS you may find yourself in a situation where you wonder what all the stuff in your library are and if they ever get used by your applications. Some stuff just sits there and begs to be deleted. But deleting stuff from /lib/ isn’t really a good idea unless you have an idea about what you delete. A simple solution is to do a complete ldd-output of your system:

ldd /bin/* /usr/bin/* /sbin/* /usr/sbin/* /lib/* /usr/lib/* | libAnalyzer.pl

This will return a list of the libraries you actually use. That way you can experiment with killing unused libs.

Remember that you may have libraries and binaries in other locations and that some statically linked binaries may have library requirements that ldd is unable to detect. I take NO responsibility for the operational outcome of this code, you should use this program in development *only* – NEVER on your own, running, system. Do not ever delete a library without understanding the consequences it may have. And NEVER delete stuff on a production-system. This is for hacking-purposes ONLY :)

libAnalyzer.pl:

#!/usr/bin/perl -Wall
# Sverre skeldoy@gmail.com (2008)
# USE FREELY AND BE A GOOD GUY! :)
while (<>) {    if ("$_" =~ "=>") {
                @tempus = split ('=>', $_);
                chop($tempus[0]);
                push(@libs, $tempus[0]); } }
print "There is a total of $#libs libraries to analyse:\n";
for ($i = 0; $i < ($#libs+1); $i++) {
$Found=0; chop ($libs[$i]);
$libs[$i] =~ s/^\s+//g; $libs[$i] =~ s/\t//g; $libs[$i] =~ s/\n//g;
        for ($j =0; $j < ($#holds+1); $j++) {
                $tested = $libs[$i];
                unless ($tested =~ m/\+/) {
                if ($holds[$j] =~ m/$tested/) { $Found=1; } } }
        if ($Found == 0) { push (@holds, $libs[$i]); } }
for ($t = 0; $t < ($#holds +1); $t++) {
@reallyTemp = split ('.so.', $holds[$t]);
push (@proper1, $reallyTemp[0]); }
@proper = sort(@proper1);
print "We found $#proper different libs in use:\n";
for ($a = 0;$a < ($#proper+1); $a++) { print $proper[$a]; }

Getting data from a table of arbitrary dimensions with Perl/MySQL

Posted in Uncategorized with tags , , , , on December 28, 2008 by skeldoy

This code takes an arbitrary amount of columns and rows from the csvData-table of a MySQL-database (csvData)

and prints it in a pretty table. The concept is pretty basic but I provide it here so that you have a shortcut to doing this

sort of thing. It may take some tinkering to do it; but once you understand the basics of the code, you may print out

any MySQL-data without knowing how much there will be. It stems from a project that I am tinkering with that

is called csv2html. This is the last step:

mysql2html.pl:

#!/opt/local/bin/perl
############################################################
# MySQL to HTML-parser.	- Sverre Eldøy (skeldoy@gmail.com) #
############################################################
use DBI;
use CGI;
$|        = 1;
$hostname = "localhost";    # where is the database?
$username = "root";         # name of the account
$password = "";             # account-password
$defaultDatabase = "test";  # We assume that there 
# is a database called test to generate dB
$databasename = "csvData";  # Name of the database
$DEBUG = 0;
$table = "csvData";
my $showDB =
  DBI->connect( "dbi:mysql:$databasename;$hostname", 
$username, $password );
my $cgi = new CGI;
my $query = $cgi->param('query');

if ($query eq "") { $showDBquery = "SELECT * from $table"; $queryNull=1;}
else { $showDBquery = "SELECT * from $table ORDER BY $query"; $queryNull=0; }

my $showDBbuildConnection = $showDB->prepare($showDBquery);
$showDBbuildConnection->execute();

$showDBbuildConnection->bind_columns(
	map { \${"main::$_"} }
    @{ $showDBbuildConnection->{NAME_lc} }
)  || die("unable to bind columns: ", $showDBbuildConnection->errstr);

$columnCount=&countColumns();$columnCount--;
&HTML();
&HEADER();
&BODY();
if ($DEBUG) {if ($queryNull != 1) {print "Q:$query";} }

&TABLE();
&TR();
for (my $var = 0; $var < $columnCount; $var++) {
	# body...
	if ($query eq "csvvalue$var") { &TDPpack("csvvalue$var"); }
	else { &TDQpack("csvvalue$var"); }
}
&TRc(); 

while ( $showDBbuildConnection->fetch() ) {
	&TR();
    for (my $var = 0; $var < $columnCount; $var++) {
		# body...
		my $tempString = "csvvalue$var";
		if ($DEBUG) { print "TS: $$tempString\n"; }
		&TDpack("$$tempString");
	}
	&TRc();
	}
$showDBbuildConnection->finish();
&TABLEc();
&BODYc();
&HTMLc();

## END OF MAIN

sub TDpack() { print "\t\t\t<td>@_[0]</td>\n"; }
sub TDQpack() { print "\t\t\t<td>
<a href=\"mysql2html.pl?query=@_[0]\">@_[0]</a></td>\n"; }
sub TDPpack() { print "\t\t\t<td><b>@_[0]</b>
<a href=\"mysql2html.pl\">X</a></td>\n"; }
sub TR() { print "\t\t<tr>\n"; }
sub TRc() { print "\t\t</tr>\n"; }
sub TABLE() { print "\t<table border=1px>\n"; }
sub TABLEc() { print "\t</table>\n"; }
sub HTML() { print "Content-type:text/html\n\n<html>\n";}
sub BODY() { print "<body>\n";}
sub HTMLc() { print "</html>\n";}
sub BODYc() { print "</body>\n";}
sub HEADER() { print "<title>mysql2html</title>\n";}

sub countColumns () {
	my $showDBquery           = "DESCRIBE $table";
	my $showDBbuildConnection = $showDB->prepare($showDBquery);
	$showDBbuildConnection->execute();
	$showDBbuildConnection->bind_columns
( \$desc1, \$desc2, \$desc3, \$desc4, \$desc5, \$desc6 );
	$columnCount = 0;
	while ( $showDBbuildConnection->fetch() ) {
	    if ($DEBUG) { print "$desc1, $desc2, $desc3, 
$desc4, $desc5, $desc6\n"; }
	    $columnCount++;
	}
	$showDBbuildConnection->finish();
	if ($DEBUG) { print "CC: $columnCount\n"; }
	return $columnCount;
}

Perl+MySQL+DBD::Mysql on Mac OS X Leopard Server

Posted in Uncategorized with tags , , , , , , on December 28, 2008 by skeldoy

The DBD::mysql isn’t compatible with the 64-bit version of MySQL that comes with the Leopard Server.

When you sudo cpan install DBD::mysql you end up with a lot of compile-errors in dbdimp.c

You actually have to downgrade your MySQL-server-app to a 32-bit version in order to get it working.

You just have to download the 32-bit package from the mysql-site and rerun sudo cpan install DBD::mysql

Speeding up with Inline-C in Perl code

Posted in Uncategorized with tags , , , , , , on December 28, 2008 by skeldoy
Computationally heavy Perl-code is no match for compiled C-code in terms of speed. 
You can choose to create small C-applications that you run with backticks from Perl, 
but that could loose you some speed to overhead, it may look and be nasty or the 
problem just ain't solved that way because of structural issues with your code.
Luckily there is a fancy, automagical way of doing C-code inside Perl.
Inline-C will actually compile functions and call them from the Perl-code.
That way you can retain most of your original code while speeding up the bits you
believe to be the tight parts.
Example:
#!/usr/bin/perl -w
$|=1; # for this example we need to spit out to stdout without delay
use Inline C; # You may need to sudo cpan install Inline::C first
use Inline C => Config => OPTIMIZE => '-O3'; #sets the optimization flags for your compiler
print fib(35); # runs a Pure-Perl Fibonacci-routine that returns the 35'th fibonacci number
print fibc(35); # runs an Inline-C variant of the same basic algorithm as above.
sub fib { # Perl-fibonacci-routine 
    my($n)=@_;
    if ($n<2) {
	return $n;
    }
    else {
	return fib($n-2)+fib($n-1);
    }
}
# Then we end the Perl-code and inline with a C-version of the algorithm.
__END__
__C__

int fibc (int nummer) { if (nummer <2) return nummer;
else return (fibc(nummer-2)+fibc(nummer-1)); }


If you run this code you will see how much faster the C-version of the algorithm is.
For a computationally heavy thing such as this, this is so much easier than working with
wrappers and other stuff. All the compilation is handled automagically in the background;
When you run perl the C-code automagically compiles down in an ./_Inline/ directory and stays
there until your original code changes. The compile time is (well in this case anyway) insignificant.
Follow

Get every new post delivered to your Inbox.