Saturday, January 31, 2009

10 Things You Might Not Know About MySQL

Customer Support Web 2.0 Style

If you've been calling up the customer helpline only to find yourself on hold for over 10 minutes waiting for the first-level tech support script monkey to ask you a bunch of totally unrelated questions, then you ought to check out GetSatisfaction.com . It's like a social network of users who use a product and more often than not, you'll also find staff who know what they're dealing with to pitch in and help out.

Get People To Your Meetup on Meetup.com


If you're getting complete strangers from your region together for a meetup on just about anything, check out http://www.meetup.com . It helps organize the meets by keeping a count of how many people are visiting, hosting polls & pictures, and pretty much anything you would want to do for a meet up.

PostgreSQL vs MySQL

LINQ to SQL and Entity Framework

UML Use Case - Includes vs Extends

A couple of developers I know asked me about the includes and the extends for use cases. "includes" is used when the included use case is always executed as a part of another user case. "extends" is used when a use case is executed as a part of another only when an exceptional condition occurs.

Thursday, January 29, 2009

More Linq2Entities From The Real World

I've built a WCF service that takes as a parameter an entity object with a reference to another entity (a foreign key-primary key relationship). When I try adding it to the database (context object) with LINQ, I get the following exception:

The object cannot be added to the ObjectStateManager because it already has an EntityKey. Use ObjectContext.Attach to attach an object that has an existing key.

I tried manually attaching the entity reference, but that didn't seem to work either so I finally had to get the primary key value of the reference, re-fetch the object from the database and set the reference again with the newly-retrieved object.

They make this so much harder than it should be :-(

Wednesday, January 28, 2009

WCF in the Real World - a case of two definitions for a class

I've been using 2 WCF web services on my project - Service1.svc returns an entity object which I have to pass to Service2.svc. Now, after I add a service reference to both in Visual Studio, I get 2 classes - Service1.Entity and Service2.Entity and I can't cast one to the other.

The solution is to either take the properties of one class and put it into another within the client-side code, or put the class into a class library used at both the server and the client side. At the client side, you simply have to add a reference to the DLL before you add the service reference to prevent svcutil from creating the class in a new namespace.

UPDATE: You can find more about it here and here.

Tuesday, January 27, 2009

Firefox CacheIt Plugin

The Firefox CacheIt plugin lets you view cached versions of pages - it comes in pretty handy if the original source server is not accessible or if you want to view an older copy of the page.

CacheIt uses the Google Cache, Way-Back Machine, and the Coral (...and perhaps Dot Cache too?) caches to get cached copies of the page.

I used the Way-Back Machine to get a copy of David's Diary on Getting a Girlfriend, a popular Internet diary/blog from the late 90s. David's account no longer exists on the server so the diary was lost forever till Way-Back Machine traveled back through time and space and fetched a copy for me :-)

Monday, January 26, 2009

Increasing Wanda's Vocabulary

Wanda is the fortune-telling fish you can add onto your *nix menu bar. When you click on her, she displays a random quote from William Shakespeare, Mark Twain, or other humorous quotes and riddles. If you don't have it, right-click your menu bar, click Add to Panel, select Fish and click Add.

Behind the scenes, Wanda relies on the "fortune" command line application that displays random quotes from the fortunes file located at /usr/share/games/fortunes. You can view a list of all messages used by fortune from the file /usr/share/games/fortunes/fortunes. To edit this file, do the following:

cd /usr/share/games/fortunes
sudo vi fortunes

At this point, the vi editor starts up. If you aren't familiar with the vi editor, you can use gedit instead - type "gedit fortunes" instead of "vi fortunes". You have to end every entry with a "%" sign on a blank line. After you've edited and saved the file, type the following command

sudo strfile fortunes fortunes.dat

Now, Wanda (and the command-line fortune) will display the new messages which could be anything from the Java Factoid of the Day, or a quote from Star Wars - "Who's the more foolish: The fool, or the fool who follows him?".

Sunday, January 25, 2009

HttpException: The Controls collection cannot be modified because the control contains code blocks

A team mate had a pretty odd error from ASP.NET that comes up like this...

Server Error in '/LaaziWeb' Application.

Stack Trace:

[HttpException (0x80004005): The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).]
System.Web.UI.ControlCollection.Add(Control child) +8674071
System.Web.UI.PageTheme.SetStyleSheet() +478
System.Web.UI.Page.OnInit(EventArgs e) +8694828
System.Web.UI.Control.InitRecursive(Control namingContainer) +333
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +378

The error was a little hard to put a finger on, but I eventually traced it to a script that used a <%= txtBox1.ClientID %> with a document.getElementById. The script was in the HEAD section of the page and to make the exception disappear, I moved the script into the BODY section.

Cooliris: Web Image Viewer

A co-worker introduced me to the Cooliris, a remarkably cool image browser for web galleries. It gives you an slightly iPhone-like view of the gallery and goes a step further in diminishing the boundary between what's on the web and what's on your desktop.

I went onto the Cooliris website with Firefox running over Ubuntu 8.10, and I got a "Cooliris is not supported on this browser." :-(

Friday, January 23, 2009

Seagate firmware upgrade wreaks havoc with 500GB HDDs

The firmware upgrade Seagate provides to fix the problem with 1TB Barracuda drives seems to work, except that when you've got the 500GB Barracuda, it bricks your disk.

It's yet another case of lack of testing... their test engineers probably weren't curious enough to think "What if we tried the firmware on a system that also has 500GB drives?" Unlike what many people imagine, test engineers are more than just script monkeys - they've got to figure out ways to break something that seems to work perfectly.

Starting off with GDB

The GNU Debugger is pretty handy when developing applications in C for the Linux platform. Using it is pretty simple...


Compiling for Debug

Compile your program with gcc, adding a "-g" option to include debugging symbols

Example: gcc -g nitin.c



Run with Debugger

Execute GDB, providing the executable as a parameter

Example: gdb a.out



Start Execution

Get into the main method by typing "start main" followed by any parameters

Example: start main hello



Step Through

Go line-by-line by typing "n" or "next"



Watch

Display variable values using the "print" command

Example: print argv[1]



Breakpoints

Set a breakpoint with the "b" or "break" command followed by the filename:line number

Example: b nitin.c:25



Continue

Run till the next breakpoint using "c" or "continue"



End

Press Ctrl+C to stop execution, and "q" or "quit" to close GDB.

Thursday, January 22, 2009

HOWTO: VPN from Ubuntu 8.10

I have a Microsoft Windows based network at the office and they've setup a VPN connection for me to be able to hook up to the servers to take care of a couple of ASP.NET applications and manage the server.

Ever since I installed Ubuntu 8.10, I've been a bit disconnected from the office as I can only access the services exposed by the web gateway, so I finally decided to setup a VPN connection from Linux.

I started off by clicking on the network icon on the top-right of the menu bar and then Configure VPN (under VPN Connections). The VPN tab had the Add button disabled so I went to the command prompt (Application, Accessories, Terminal) and typed the following command:
sudo apt-get -y install network-manager-pptp

I then entered my password (for the sudo), after which it downloads and installs PPTP support. To make sure Add button under VPN is now enabled, I also type the command:
sudo NetworkManager restart

Now, I simply click the network icon (from the top-right of the menu bar), click Configure VPN (under VPN Connections), I click the Add button, type in the IP address of the VPN server for the Gateway, my ActiveDirectory (from the Windows domain) username and password, followed by the domain name. I click the Advanced button and check the "Use Point-to-Point encryption (MPPE)" checkbox and click Ok on both dialog boxes.

To connect to the VPN, I click the network icon and under VPN Connections, I select the VPN connection that I just created.

Going Multi-Lingual With Parallel Folders in ASP.NET

As with any other programming problem, there are many ways to go about serving pages in multiple language to your visitors. The approach I'm trying out is using a folder for each language (EN, HI etc) and getting pages from both folders to point to the same code behind file. ASP.NET does require you to place the code behind file outside the App_Code folder, which did seem a little odd to me at first.

In the end, I ended up with a folder structure a little like this:
en
--Admin
----Console.aspx
--User
----Listing.aspx
hi
--Admin
----Console.aspx
--User
----Listing.aspx
CodeBehind
--Admin
----Console.cs
--User
----Listing.cs

You might want to try the globalization & localization features in ASP.NET. They are totally awesome when you don't need to change the look of a page by much (think about changing left-to-right to right-to-left) when displaying the same page in a different language.

Java OpenGL (JOGL)

I'm hoping to try out the Java OpenGL wrapper tonight. It's based on the JSR 231 spec. You can find some sample source code on Wikipedia at:
http://en.wikipedia.org/wiki/Java_OpenGL

You can get the JOGL binaries for your platform on the JOGL site here. It's for the May '08 release. If you've been working with the C API for OpenGL, the JOGL will seem pretty close, which makes it an easy transition.

Finding OpenSource Developers

If you're looking for developers to work on your open source project, you ought to try posting to the Help Wanted section of SourceForge at:
https://sourceforge.net/people/

Tuesday, January 20, 2009

ADO.NET Data Service

If you use LINQ, you'll definitely like ADO.NET Data Services. It lets you perform LINQ queries remotely so your database can be with a web server behind a firewall, and the client can access the database through the web server.

The ADO.NET Data Service is a class that inherits from a DataService generic class (the context class is used for the generic type). Example:
public class WebDataService : DataService<NitinEntities>


The InitializeService method is used to set access privileges. Example:
public static void InitializeService(IDataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
}


You can add additional methods that return the IQueryable generic type. Think of them as the equivalent of views over tables.

The client application needs to have a service reference. After adding the reference, you'll find a context class (WebDataService.NitinEntities) that you can use. You can run LINQ queries over the context remotely.

Evolving SlideShare

SlideShare has been given a makeover - check out the new Embed feature. From too many icons and annoying hover-over DIVs that cover up icons, they went on to display Blogger, Facebook, Twitter and a "more" link.

SlideShare is also integrated with Google authentication if you are posting to Blogger.

Spring 3 MVC CodeMash 2009

Check out this SlideShare Presentation:

LINQ to Entity Trash

I know, I know, everyone's talking about usin LINQ to Entities instead of LINQ to SQL, but there's so much that simply doesn't work when using LINQ to Entities.

First off, if you need to run a stored procedure that has nothing to do with any of the entities you are working with, the Entity framework simply can't handle it.

Secondly, there's the lack of support for using Contains to mimic SQL's IN operator. (You can use the Contains method as the equivalent of SQL's LIKE)

The Entity framework does have potential and version 2.0 is something I'm really looking forward to, but what I'm saying is that it is just not fully developed to use in all of your applications yet.

Monday, January 19, 2009

Quiz Engine: XML Parsing in Java

I've made up a port of the Quiz Engine in Java, and I've re-structured the source code repo to accomodate the port too. The XML parsing but in Java looks a little messy; I put it together as a hack to simply work.

You can find it on sourceforge at:
https://sourceforge.net/projects/quiz-engine/

JAXP Switching Implementations

I was thinking about the kind of effort it would take to switch between different implementations underlying the JAXP API so I did a Google search and came across an article on the Sun website with the following. It basically means you can switch between JAXP implementations with absolutely zero code changes.

The factory APIs let you plug in an XML implementation offered by another vendor without changing your source code. The implementation you get depends on the setting of the javax.xml.parsers.SAXParserFactory, javax.xml.parsers.DocumentBuilderFactory, and javax.xml.transform.TransformerFactory system properties, using System.setProperties() in the code, <sysproperty key="..." value="..."/> in an Ant build script, or -DpropertyName="..." on the command line. The default values (unless overridden at runtime on the command line or in the code) point to Sun's implementation.

iText: A PDF library for Java/.NET

I've been trying the iText library lately. It makes generating PDFs quite simple. Check out this C# code snippet of inserting an image (JPEG, in this case) into a PDF:

Document doc = new Document();
PdfWriter pdf = PdfWriter.GetInstance(doc, new System.IO.FileStream("fileout.pdf", System.IO.FileMode.Create));
doc.Open();
doc.NewPage();

#region Getting my byte array
//You don't have to do this if you are using a database - read the image as a byte array from the database instead
FileStream fstream = new FileStream(@"C:\rosewhite.jpg", System.IO.FileMode.Open);
byte[] byteBuf = new byte[100000];
int actualSize = fstream.Read(byteBuf, 0, 100000);
byte[] byteBufNew = new Byte[byteBuf.Length];
for (int i = 0; i < byteBuf.Length; i++)
{
byteBufNew[i] = byteBuf[i];
}
#endregion

//provide the byte array you got from the database in place of byteBufNew
doc.Add(new Jpeg(byteBufNew));
doc.Close();

You can do lots of other stuff with iText too, such as inserting tables, add digital signatures, bookmarks etc. iText is a free library and can read more about it here.

Sunday, January 18, 2009

List of Software Development Methodologies


Software Project Methods

From: craigwbrown,
2 days ago


Software Project Methods
View SlideShare presentation or Upload your own. (tags: pmi pmbok)



A summary of the more popular software develpment processes and methods.



SlideShare Link

XML Parsing .NET Example

I spent about an hour yesterday cooking up a sample on XML parsing and I came up with a minimalist quiz engine. It reads an XML file, gets the users answers, and displays a score at the end.

I've uploaded it onto SourceForge, so check it out at:
https://sourceforge.net/projects/quiz-engine/

Entity Framework - Don't Forget to Detach

Often in the web programming model, we make use of disconnected data sets. When using LINQ-to-Entity to fetch data, you have to remember to call the Detach method of the context. If you do not detach the object, the context continues to maintain a reference which keeps it from being garbage collected.

Here's an example:
public Customer GetById(int aId) {
DataEntities de = new DataEntities();
var retVal = (from iterCust in de.Customers
where iterCust.Id = aId
select iterCust).FirstOrDefault();
de.Detach(retVal); //detach the object from the context
return retVal;
}

You do not have to do this when you set the NoTracking MergeOption (set de.Customer.MergeOption).

More On Writing XML In Java

After trying JDOM, I just had to check out the built-in XML features of the Java Development Kit. I used the Java API for XML Processing with the Apache Xerces underneath (included with Sun's JDK 6). Here's the sample I came up with:

import javax.xml.parsers.*;
import org.w3c.dom.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import java.io.*;
import javax.xml.transform.stream.*;
//SNIP
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DOMImplementation di = dbf.newDocumentBuilder().getDOMImplementation();
Document doc = di.createDocument("http://example.com/", "rootElement", null);
Element el = doc.createElement("childElement");
doc.getDocumentElement().appendChild(el);
Transformer trans = TransformerFactory.newInstance().newTransformer();
DOMSource ds = new DOMSource(doc);
FileOutputStream fostr = new FileOutputStream("xmlout.xml");
StreamResult strResult = new StreamResult(fostr);
trans.transform(ds, strResult);
fostr.flush();

Saturday, January 17, 2009

CSS Generic Fonts

When specifying fonts through CSS using the "font-family" attribute, you might have users who can't display some of the text correctly when they don't have the font you are using. Sure, you can provide multiple fonts with a comma separated list, but does it have to be so hard?

CSS provides 5 generic fonts that you can provide at the end of the CSS list so you don't have to list every font in existence just to get your page to display in a particular way. The 5 generic fonts are: cursive, fantasy, monospace, sans-serif, and serif.

Reflection in .NET

The Microsoft .NET Framework makes it really simple to dynamically load a type based on configuration info provided. It comes in pretty handy for building plug-in based systems.

In today's code sample, we'll start off with a simple class:

namespace GateLib
{
public class Neptune
{
public string GetAString()
{
return "Nile River";
}
}
}

After compiling the class into a class library (DLL), we start work on our code to call the class method. Let's build a console application for simplicity sake. Here's the code we put into the Main method:

Assembly asm = Assembly.LoadFile(System.Environment.CurrentDirectory + "\\GateLib.dll");
Type ty = asm.GetType("GateLib.Neptune");
MethodInfo meth = ty.GetMethod("GetAString");
ConstructorInfo ci = ty.GetConstructor(Type.EmptyTypes);
object obj = ci.Invoke(null);
object retval = meth.Invoke(obj, null);
Console.WriteLine(retval.ToString());
Console.Read();

In this code sample, I'm using the default constructor for the Neptune class that takes no parameters (notice the Type.EmptyTypes and the null in the ci.Invoke), and the method GetAString that takes no parameters (it's the null in the meth.Invoke).

After compiling the console application, I place the class library in the same folder as the EXE, and execute the console application to get "Nile River" on-screen.

I know it doesn't do much but it's just a start. You'll probably end up doing so much more with it.

JDOM For Generating XML

As you've probably figured out from my blog, I'm an ASP.NET C# web developer who loves trying out alternative technologies. There has always got to be another way to do something and if there isn't, then it's time to fire up the IDE and write some open source software!

After being pretty impressed with the XML API for writing XML documents with the Microsoft .NET Framework, I wanted to check out what Java had to offer. At the start, it was pretty confusing as there were so many different libraries and APIs so I didn't know what to pick. When I asked around, a developer suggested that I try out JDOM. JDOM is a pretty simple library for working with XML and is pretty close to Microsoft .NET's API. I decided to take it for a spin and here's what I came up with:

import org.jdom.*;
import java.io.*
//SNIP
Document doc = new Document();
Element elroot = new Element("root");
elroot.setText("This is the root");
doc.addContent(elroot);
output.XMLOutputter xo = new output.XMLOutputter();
FileOutputStream fos = new FileOutputStream("xmlout.xml");
xo.output(doc, fos);

JDOM's simplicity makes it very appealing to use when dealing with small amounts of data.

Friday, January 16, 2009

MS Office 14 Alpha Screenshots


ArsTechnica has a couple of screenshots of MS Office 14 from the Alpha version released earlier this week. The new version features the ribbon interface for Visio, the Office Anytime update (to purchase additional features), and a USB Office device option (to take MS Office with you to work when you don't have MS Office installed on another device?).

There hasn't been a major shift from the Office 2007 interface, which is a big plus as firms don't have to re-train their staff to use a new interface.

Seagate's 1TB Barracuda Bug

Seagate has been experiencing problems with the 7200.11 Barracuda terabyte hard drives (ST31000340AS, but not the ST31000333AS). A defective firmware is the cause of the failure and the replacement drives that Seagate ships out have the same problem.

On the Seagate website, they still have a banner up (saying "The Barracuda 1 TB Drive in action") advertising their 1 terabyte model instead of the 1.5 terabyte model, which isn't affected by the bug. I don't know about them, but if I had a bigger hard drive, I'd switch all my banners to advertise the bigger one especially if the smaller one had a bug.

What's New for Developers in SQL Server 2008


SQL Server 2008 Overview

From: ukdpe,
1 month ago


SQL Server 2008 Overview
View SlideShare presentation or Upload your own. (tags: sql 2008)






SlideShare Link

Using Frameworks With PHP


Rasmus, Think Again! Agile Framework == Happy Php Developer

From: arnoschn,
3 months ago





Talk was held during the PHP Conference in Barcelona (27.09.2008), which was also attended by Derick Rethans, Scott MacVicar and other international speakers. It shows the advantages of using a php framework vs. spaghetti code for web application development in an agile manner.
A simple example based on the Akelos PHP Framework shows you how to implement a fulltext search in less than 20 minutes.



SlideShare Link

Thursday, January 15, 2009

Hello World With GTK+ Programming

Fixing the "Package gtk+-2.0 was not found in the pkg-config search path" error
OR
getting the Hello World GTK+ example to compile.

Today, I thought I'd try my hand at GTK+ programming. Win32 GUI programming was fun, and I didn't go all the way till the edge of the world with it, but I wanted to try something different for more insight.

I started off by looking at the Hello World GTK+ tutorial here, and tried compiling the following code.

#include <gtk/gtk.h>

int main (int argc, char *argv[] )
{
GtkWidget *window;

gtk_init (&argc, &argv);

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_show (window);

gtk_main ();

return 0;
}

Compilation failed with the error "Package gtk+-2.0 was not found in the pkg-config search path" so I figured I didn't have the GTK+ development library. A quick search from the Synaptic Package Manager revealed that there was a libgtk2.0-dev package that I didn't have installed.

As soon as I installed the package, compiled the source code and executed the program, a GTK+ window popped up! This could be a whole new beginning for me. Let's so how far it goes.

A Sick Day Off From My Blog

Hi!

I'm taking a sick day off from my blog today. Sorry, I'm just feeling under the weather.

Hope you're having a good day out there.

-Nitin

Wednesday, January 14, 2009

Blogger Text Size

I seem to be having a problem with the text size on my blog. The first couple of articles on my blog look normal, but after the 3rd or 4th entry, the text size is small. I'm guessing it's a temporary thing that will go away just as mysteriously as it appeared.

In the meanwhile, if you're finding it difficult to read the text, use your browser to increase the text size. Under the View menu of your browser, you'll have an Increase Text Size, or Zoom, or something similar.

If the problem persists tomorrow, I'll see if I can create a workaround.

Introduction to OpenGL


SIGRAPH Asia 2008 Modern OpenGL

From: Mark_Kilgard,
4 days ago


SIGRAPH Asia 2008 Modern OpenGL
View SlideShare presentation or Upload your own. (tags: gpu kilgard)



A long-time implementer of OpenGL (Mark Kilgard, NVIDIA) and the system's original architect (Kurt Akeley, Microsoft) explain OpenGL's design and evolution. OpenGL's state machine is now a complex data-flow with multiple programmable stages. OpenGL practitioners can expect candid design explanations, advice for programming modern GPUs, and insight into OpenGL's future.



These slides were presented at SIGGRAPH Asia 2008 for the "Modern OpenGL: Its Design and Evolution" course.



Course abstract: OpenGL was conceived in 1991 to provide an industry standard for programming the hardware graphics pipeline. The original design has evolved considerably over the last 17 years. Whereas capabilities mandated by OpenGL such as texture mapping and a stencil buffer were present only on the world's most expensive graphics hardware back in 1991, now these features are completely pervasive in PCs and now even available in several hand-held devices. Over that time, OpenGL's original fixed-function state machine has evolved into a complex data-flow including several application-programmable stages. And the performance of OpenGL has increased from 100x to over 1,000x in many important raw graphics operations.



In this course, a long-time implementer of OpenGL and the system's original architect explain OpenGL's design and evolution.



You will learn how the modern (post-2006) graphics hardware pipeline is exposed through OpenGL. You will hear Kurt Akeley's personal retrospective on OpenGL's development. You will learn nine ways to write better OpenGL programs. You will learn how modern OpenGL implementations operate. Finally we discuss OpenGL's future evolution.



Whether you program with OpenGL or program with another API such as Direct3D, this course will give you new insights into graphics hardware architecture, programmable shading, and how to best take advantage of modern GPUs.



SlideShare Link

Working with Multiple SVN Repositories

At work, I've got 2 source code repos (repositories) to work with - one that is common to all the projects in the firm, and the other that is project specific.

Normally, that would mean I have to use 2 different repos, but instead we've got external references from our project-specific repo to the common repo so whenever I fetch the latest revision from the project-specific repo, the common repo is retrieved as a sub-folder.

To create the external reference, I defined the "svn:externals" property and used the value format " ".

Tuesday, January 13, 2009

Open Source Bounties

If you're out of work and are looking for a software development job, you could think about becoming a software bounty hunter. It's fun, it's a paid opportunity, and you would be doing the open source community a whole lot of good.

There are a couple of websites that list bounties, such as Open Source Experts, that you can look up for bounties. Bounties are usually small contributions by users for a feature that add up to form a larger bounty. Often, bounties are offered by firms to promote development in a particular area.

Stuff People 'Paste'

I always thought the only text people posted on pastie.org and other similar sites was source code.

While browsing through some of the 'pastes' today, I came across compiler output (pointing out errors reported by the compiler), diff output, configuration parameters, command line statements (possibly instructions), ASCII representations of directory tree structures, CSS, and some hexadecimal values.

MSN Web Messenger Ignorant

Every day, I use MSN's web messenger via Mozilla Firefox 3 on Ubuntu Linux to IM my co-workers at the office.

When I surf to webmessenger.msn.com , MSN claims that it doesn't support my browser and suggests that I instead use: MS IE 5 or later, Netscape 7.1 or later, or Mozilla 1.6 or later, *running in MS Windows*.


The web messenger works fine for me either way - I just ignore the message and click Start MSN Web Messenger.

Monday, January 12, 2009

Convincing People to Go Ubuntu

Yesterday, I got a co-worker to switch to Ubuntu 8.10 as a primary operating system. The Windows key-Tab for switching between windows had her impressed. We use Sun's VirtualBox to run Windows XP so we can work on Microsoft Visual Studio 2008. The installation went perfectly well as both the partitions were primary partitions.

Today, I convinced another co-worker to use Ubuntu - it was mostly the Compiz Fusion 3D desktop cube that did it for him. Running Sun's VirtualBox for Visual Studio made the deal. However, the installation didn't work - an error was reported at the partitioning phase and apparently, the installer doesn't re-size the extended partition to make room for itself.

Windows is still a part of daily work though... it comes as a part of being in a team developing with the Microsoft .NET Framework 3.5.

VirtualBox Raw Disk Boot Fails

I tried to use a raw partition as a virtual disk and tried booting Windows XP. The farthest I could get was the boot loader followed by a text-mode progress bar on selecting Windows XP and it would just hang at that point.

Booting Ubuntu 8.10 off the raw partition didn't go much further either - the bootloader just choked.

I guess all I can do with a raw partition is use it alongside a virtual disk to access data :-(

Ping with .NET

.NET makes pinging a network host to check for availability a piece of cake.

Step 1: To start off with, import the namespaces System.Net.NetworkInformation and System.Net

using System.Net.NetworkInformation;
using System.Net;

Step 2: Instantiate the Ping class

Ping p = new Ping();

Step 3: Call the Send method of the Ping object with the hostname as the parameter. Store the return value as a PingReply object.

PingReply pr = p.Send(@"www.google.com");

Step 4: From the PingReply object, obtain the ping status from the Status property, the time from sending the ping request to getting the ping reply in milliseconds from the RoundtripTime property, and the IP address of the host from the Address property.

IPStatus status = pr.Status; //IPStatus.Success
IPAddress ipAddr = pr.Address;
long pingTime = pr.RoundtripTime;

The IPStatus enumeration has many different values to describe the problem, if any does occur. For a simple check, you can simply compare the value with IPStatus.Success.

Sunday, January 11, 2009

DNS Query from .NET

Resolving a host name to an IP address (or several IP addresses) has never been simpler - .NET provides the GetHostAddresses method for the System.Net.Dns class that returns an array of IPAddress objects.

Here's a debugger view:

VirtualBox Guest Resizing

When running Windows XP in VirtualBox within a window, I noticed I could only set the resolution up to 800x600 (Display Properties | Settings), which had me disappointed. But, when I turned to a co-worker's screen, I saw a maximized VirtualBox window entirely filled with the Windows XP host and then my jaw dropped!

I set VirtualBox to full-screen on my system and I had the Windows XP guest doing a 1280x800 (the max. for my notebook's LCD panel).

I'm so loving VirtualBox now.

WCF services on IIS 7

If you're moving your ASP.NET WCF services from IIS 6 to IIS 7, you might not have the SVC handlers added and the 404.3 error might show up:


HTTP Error 404.3 - Not Found

The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.


This fix is to simply need to register the service models with IIS 7. To do this, you have to execute "ServiceModelReg.exe -i" from within %windir%\Microsoft.NET\Framework64\v3.0\Windows Communication Foundation (leave out the 64 if you're running a 32-bit version of Windows)

Saturday, January 10, 2009

Measuring Blog Success


A Framework for Measuring Blog Success

From: gregverdino,
2 years ago





A framework and recommended "starter tool kit" for measuring and understanding the success of your blog.



SlideShare Link

Agile Software Development Overview


Agile Software Development Overview

From: srogers74,
14 hours ago





A high-level snap shop of Agile concepts.



SlideShare Link

ListView On An EntityDataSource - Not As 'Smart'

Hooking up the ListView control to an LinqDataSource is really cool - the ListView can tell that a column is an identity column so the textbox for inserting the ID is automatically removed.

However, using the ListView with an EntityDataSource seems to be a less-intelligent solution as the textbox for inserting IDs is displayed again, although the value is ignored. If you think that's bad, wait till you try using it with a table that has a foreign key reference. :-P

Friday, January 9, 2009

ListView: A GridView With Insert Capabilities

When building applications with ASP.NET, the GridView control is particularly useful in displaying and editing data. However, the GridView lacks the ability to create new entries. That's where the ListView control from ASP.NET 3.5 provides useful. When used with the Grid layout, the ListView control provides an additional row at the bottom of the grid to insert new rows. It also provides an enhanced paging user interface.

Palm Pre WebOS

Palm unveiled the new WebOS which powers the Palm Pre smart phone. Applications for the Palm WebOS can be built with standard web development tools, which means you can carry forward your HTML and Javascript skills to the platform.

From a user's perspective, the focus of the WebOS seems to be convergence - it provides the ability to merge emails from multiple mailboxes, combine multiple contact lists (MS Outlook, GMail etc) with social networks such as Facebook, and calendars. It enables users to run multiple applications simultaneously, switching between them just as one would switch between multiple browser tabs.

The Palm Pre itself packs quite a punch with bluetooth, 802.11g WiFi, GPS, 8GB storage, accelerometer, touch screen and a sliding keyboard. Palm Pre units will be available to Sprint customers.

Microsoft Windows 7 Beta Download

The beta release of Windows 7 was made available for download on the Microsoft website here. The Microsoft website was down for quite a while as users hit the site hoping to get ahead of the crowd and claim one of the 2.5 million activation keys.

Copies of the beta are also available on torrent networks.

Google Chrome 2 Pre-beta

Google's Chrome browser has reached the pre-beta stage of version 2.0. The new version aims to make the browser more complete and narrow the gap with competing browsers by offering form field autocompletion, page-level zoom, browser profiles, and browser-script support.

To get access to the v2.0 pre-beta release, download the channel changer from here and use it to change your browser channel from Stable to Developer Preview.

The Most Shameless Apple Knockoffs


The Most Shameless Apple Knockoff

From: candyweb,
3 weeks ago








SlideShare Link

Remote Desktop on VirtualBox 2.10

The remote desktop display feature in Sun Virtual Box 2.10 is really cool. I plan on using it to install virtual machines on old laptops and desktops for running Linux. As I don't have the space to put up the old computers, I can simply stow them away in a cupboard and access them remotely.

If you haven't read the manual, here's how you can setup remote desktop access...

With the virtual machine turned off, go to the settings for the virtual machine and go to the Remote Display section. Keep the enable VRDP server checkbox checked, enter a Server Port (3389 is already taken, if you've enabled Remote Desktop from Windows, select Authentication Method "Null" (for private networks only; this allows anyone to connect from the network without using a password), and click Ok.



When running the virtual machine, you can go to the Devices menu to toggle Remote Display, if it isn't already turned on.



You can now connect to the virtual machine using the standard Windows Remote Desktop client.

Thursday, January 8, 2009

Beej's IP v6 C-Programming Guide

I did a Google search today, hoping to revive my C socket programming skills and came across Beej's guide. Those of you who learned C programming around my time would remember Beej's guide as the best quickstart guide to C Socket programming that ever was.

Well, now Beej's guide just got better. Last month, the guide was updated to include a section on implementing IP v6 so you can fire up your browser to surf to this URL and print yourself a copy of the guide to hold along your screen while you re-discover your C socket programming abilities.

Asynchronous Service Calls

When adding a service reference, Microsoft Visual Studio 2008 only generates synchronous method calls to the services. You can easily change this by clicking the Advanced button, and...

Add Service Reference dialog box
...checking the Generate asynchronous operations checkbox.

Check the generate asynchronous operations checkbox

It now generates the Begin*, End* and *Async methods for you to call from your application.

If you've already added the service references, you do not have to remove-and-add them to generate the asynchronous proxy methods - instead, right click the service reference and select "Configure Service Reference".

OLPC Moves To Windows

I know the news of the OLPC (One Laptop Per Child) shipping with Windows last November would've come as a shock to most of you because you wouldn't expect to wake up one morning and read it in the paper - it would seem too much like a prank somebody was playing on you.

OLPC now goes a step further by pulling out of the Sugar project and cutting down on staffing. However, on the positive side, the OLPC is also aiming at a model where it can distribute laptops for free - the "$0 laptop"! You can find a statement by Nicholas Negropon here.

Wednesday, January 7, 2009

Introducing IBM Lotus Notes and Domino 8.5


Introducing IBM Lotus Notes and Domino 8.5

From: tcoustenoble,
23 hours ago





http://www.ibm.com/lotus/notesanddomino

With IBM Lotus Notes and Domino 8.5, world-class business e-mail and collaboration take another exciting step forward, offering new approaches to enhance efficiency and creativity, while extending the value of current investments.



SlideShare Link

2 Terabyte SD-XC card announced

The SDXC card format was announced today at the Consumer Electronics Show 2009. The new format would support capacities of up to 2 terabytes and a transfer rate of 300MB/s.

The SDXC specification will be published at sometime around March 2009. The SDIO and SDHC specifications will also be updated to enable higher data transfer rates.

CES 2009

The Consumer Electronics Show 2009 is on in Las Vegas and CNET has been covering the new products on its website.

Among the announcements are the CES are

BlackBerry Curve 8900 availability from T-Mobile

The light-weight device includes Bluetooth, GPS and WiFi capabilities but lacks 3G. It has a 3.2MP camera and supports microSD/SDHC cards of up to 16GB.

Asus Eee PC T91 announced

The Asus Eee PC T91 features a GPS receiver, TV tuner, and an FM transmitter mated with a 9-inch display, Windows XP and Intel's Atom processor.

HP Pavilion DV2 - the AMD Neo Debut

Hewlett-Packard brings about a new genre of portable computers, somewhere between netbooks and notebooks. This may be just another marketing gimmick to add a larger screen to a netbook, but it gives choice to the consumer and that's what the CES hopes to achieve.

Dr. Dobb's Journal and PC Magazine To Go Web-Only

Dr. Dobb's Journal is going eco-friendly (eco- in ecology, as well as eco- in economy) by going web-only so I guess you can hang on to the last print edition of Dr. Dobb's Journal - it might be worth something (with all the stuff on eBay these days, who knows?) :-P

PC Magazine is going web-only too! After you've been served the January edition of PC Magazine, there won't be any more of the print editions of PC Magazine.

The idea of having a web edition seems great, mostly because you can get timely news. With a print edition, you have to wait till the next issue to read about current happenings.

Tuesday, January 6, 2009

QuickStart: Spring.NET Dependency Injection With ASP.NET

Spring.NET is a .NET port of the popular Spring framework for Java, and is most commonly used for implementing dependency injection in applications. In today's example, I'll demonstrate the usage of Spring.NET for defining a validator onto an ASP.NET page.

Let's start off by creating an ASP.NET Web Application Project. (Click the images to enlarge them and view the code snippets)

Step 1: Add References to Spring.Core and Spring.Web
Add Spring.Core and Spring.Web Reference

You can download the binaries for Spring.NET 1.2.0 here and add references to Spring.Core and Spring.Web

Step 2: Declare the spring sectionGroup in the configSections of the web.config file

Spring.NET sectionGroup in the ASP.NET web.config

Declare the context and objects sections within the spring sectionGroup in the web.config file. The context section is used to define the configuration for the Spring IoC container and the objects section is used to define objects.

Step 3: Add the spring configuration to the web.config file

IoC container declaration in web.config

In the context section, refer to the objects resource within the spring section of the ASP.NET Web.config file. Within objects, define the validation group NameValidation containing a required validator. Inject an instance of NameValidation to the NameValidator property of the Default.aspx page.

Step 4: Declare the PageHandlerFactory HTTP handler and the WebSupportModule HTTP module in the web.config

PageHandlerFactory HTTP handler

WebSupportModule HTTP module
Assuming you are working with a pre-IIS 7 web application server, you can declare the PageHandlerFactory HTTP handler and the WebSupportModule HTTP module as indicated above.

Step 5: Add a textbox and button to your page

Test user interface for Spring.NET validation
Create the user interface to enter a name on the page.

Step 6: Add the necessary 'plumbing'

Adding the code-behind
Create a Name property wrapper for the textbox created in Step 5. Add the NameValidator property. Define the button event handler to validate the data in the textbox and display the validation status.

Run the application! When the user leaves the textbox blank, the validation returns false; else it returns true.

Lenovo Adds Wii-Style Controller


Lenovo will be displaying it's new IdeaCentre A600 at the CES with a Wii-style controller. The controller will be used for more than just gaming though - you can also use it as a mouse. It can be configured with a terabyte of hard disk storage and a blu-ray DVD drive, but unfortunately it doesn't come with 8GB RAM as an option :-(

What is Dependency Injection

A co-worker asked me last week, "What is dependency injection?"

Dependency Injection is a method to reduce coupling within a system. When a component you are developing needs to make a call to another component, you wouldn't want to hard-code it, so you simply define an injection point and get a framework or dependency injector to add in that dependency (almost always) at runtime.

Dependency Injection is a specific form of Inversion of Control, which is simply the idea that components should not be coupled but instead should use some means of calling another component. For example, if you wanted to decouple your system using Inversion of Control but didn't use Dependency Injection, you could instead go with Service Locators - each component makes a request to a service locator to locate the component it needs to call.

UPDATE: I found a pretty good blog post about Inversion of Control, Dependency Injection, and Service Locator here.

Catching a Twitter Phish

For the uninitiated, phishing is putting up a site that looks just like the one that you would normally visit everyday, and collecting your username and password as you enter it on the phishing site.

Recently Twitter has attracted a new phishing scam. When you click a link and get directed to what looks like the Twitter site, and enter your username and password, the phishing site uses your identity to post links on Twitter. The idea behind the phishing scam is that people are more likely to open links that they get from their friends than from complete strangers, and the phishing site gets paid for directing traffic. Twitter is an easy target because it converts URLs with TinyURL.com so you can't see the actual URL till you click on it.

The URL of the Twitter phishing site is http://twitter.access-logins.com/login/ while the actual URL of the Twitter site is http://www.twitter.com

Monday, January 5, 2009

Splashtop - Boot In Under 5 Seconds

If you spend minutes waiting for your computer to boot up to check your email, you'd better reconsider your options. Splashtop is a Linux distribution usually distributed on a ROM chip and includes a web browser and Skype client. Some systems from Asus and Lenovo include Splashtop and you can get a list here. Systems with Splashtop include a regular operating system, such as Windows Vista or Windows XP.

Other Splashtop-like Linux-based systems also exist, such as Dell's Latitude ON, and Coreboot.

Zune 30GB Offending Code Posted Online

The source code from the 30GB Microsoft Zune players that went haywire at the turn of the year was leaked online on pastie.org.

The section of code that causes an infinite loop is here:

while (days > 365)
{
if (IsLeapYear(year))
{
if (days > 366)
{
days -= 366;
year += 1;
}
}
else
{
days -= 365;
year += 1;
}
}

If the days counter reaches 366, we enter the while loop and you've either got a leap year or you've got to start incrementing the year. Now, when the year is a leap year, the code checks if the days counter is over 366. If the days counter is exactly 366, we don't do anything and return to the while condition. The while condition evaluates to true, so we're back in the loop, we check if the year is a leap year, the days over 366 'if' condition evaluates to false again, and we're stuck in an infinite loop.

Installing Windows in Virtual Box on Linux

I was pretty excited to get VirtualBox finally running on my Ubuntu 8.10 installation so I decided to go ahead and install Windows 2008 on VirtualBox. I mounted the installation disk as an ISO image and booted up a virtual machine with 1GB RAM, 64MB video memory, and 3D acceleration. Each time I started up the installation, the CPU usage would peak to a high, the Vista installer's black-and-white text-mode screen with the progress bar would appear, then the window size would increase with complete blackness followed by a text mode window with complete blackness.

After a failed attempt at installing Windows 2008 on VirtualBox, I decided to install Windows XP instead. I mounted a physical Windows XP CD, booted up the virtual machine and the installation went on as usual. The formatting part was zippy-quick as it's a virtual machine and not a real physical disk on a real physical machine. That's the best part about installing on a virtual machine.

When the GUI portion of the Windows XP installation started, I realized that Virtual Box just wouldn't capture my mouse pointer, no matter what I did. I went ahead with the installation anyway using just the keyboard. After the installation was complete and I still had a defunct mouse pointer so I thought I'd try and setup Remote Desktop and connect to it via the Terminal Service Client in Linux. I clicked on Devices and clicked Remote Desktop and... nothing. I was hoping for a dialog box or something but none appeared. Perhaps I forgot to set something up? I then tried Install Guest Additions, went through the install in the virtual machine with the keyboard, moved the mouse, and voila! The mouse pointer was working!!!!

I then went on to install Visual Studio Team System 2008 and even as I speak, VirtualBox is emulating a physical system on which Microsoft Windows XP is installing Visual Studio 2008!!! How cool is that?! :-)

I'll tinker around with VirtualBox some more and let you know how things are flowing.

I wish the VirtualBox guys would spend more time testing the Linux version 'cos trying to get it to work was frustrating.

UPDATE: I've been wondering why Windows 2008 didn't work in VirtualBox because I was pretty sure I used it in VirtualBox before so I booted up in Windows, tried running VirtualBox again, mounted the Windows 2008 DVD and tried again. This time, I noticed a loooong pause before the Windows 2008 installer would do anything :-P

Apple Patents iGlove

Apple filed for a patent for a glove that you can use to operate a touch screen with it's electrical conductive layer.

I wonder why anyone would need one of those? A small hole in the glove on one of the finger tips would work just fine. I guess it's a matter of style over economy if you buy an iPhone, or buy anything from Apple for that matter.

I guess we're going to see iGloves popping up in Apple stores all over the world soon.

Sunday, January 4, 2009

I'd Love To Hear From You

Hi!

I know you're expecting to find a tech. blog post right here, but this one is just a message from me to you. I'd like to thank you for taking the time to visit my blog and I'd love to hear from you. Tell me what you think, tell me what you want to see more of, tell me if there's something you are working on right now that I could help out with by posting some info about it, and do make sure you tell me if there's something on my blog that you absolutely despise.

To shout back to me, leave a comment on my posts (click the link that says "comments" under each post), email me, shoot me a message on GoogleTalk or Yahoo messenger, ring me up on my phone or send me snail mail (yes, those things still exist!).

I hope you enjoy reading my blog posts as much as I enjoy writing them. I look forward to a whole new year of fun and learning.

Signing off,
Nitin Reddy

Validation Frameworks for .NET

There seem to be so many validation frameworks around for .NET that if you plan to go with something other than the mainstream, there are literally dozens.

The most popular of the lot are the Microsoft Enterprise Library Validation Application Block, closely followed by the Spring.NET validation framework (part of Spring.NET Core) and the Castle validation framework.

I came across yet another validation framework today called the .NET Validation Framework (notice the capital 'V' and 'F'). They've made a beta release of version 2 in April 2008, but the project is still in development. The developer working away at the source code are Simon Cropp and Dane O' Connor (I assure you - he has nothing to do with the Terminator :-P). The project has been in development since April 2007.

I've been investigating the Spring.NET validation framework lately and they seem to have quite a bit of interesting stuff. Once you get the hang of it, you would find it more flexible than the Enterprise Library VAB, though the VAB has a smaller learning curve and suits most application needs.

Windows 7 vs Vista vs XP

Adrian's blog on ZDNet has a comparison between Microsoft Windows 7, Vista and XP and Windows 7 has been the clear winner in almost all of the tests used for benchmarking.

It's probably still early to say much about Windows 7 as it's still in beta, but things seem to be looking pretty good.

VirtualBox 2.1.0 Install On Ubuntu Linux 8.10

Installing VirtualBox was a little bit more complex on Linux. The first time I ran the installation, it stopped at the end complaining about not finding a kernel module or the kernel headers to compile a kernel module.

VirtualBox Kernel Module Installation Error

After installing the kernel headers, I tried to run the installation again but the installation would just stop indicating that the vboxusers group already exists, so I un-installed the virtualbox-2.1 package with a "dpkg -r" and tried re-installing again, but the group was still there :-(

Anyway, so I manually remove the vboxusers group using "groupdel vboxusers" and re-install again. This time, I get a message indicating that the installation was successfully completed and the kernel module has been started.

Finally, I've got to go find the executable as there isn't an icon in "Applications". I remembered seeing a System Tools menu in "Applications" for my last install, so I figured I could just get it by logging out and logging in again, and guess what - I was right!

I launched Virtual Box, scrolled down and accepted the license agreement, cancelled the registration (I'll do it another time, I promise!) and went ahead to create a virtual machine to try a boot. It worked beautifully!

VirtualBox 2.1.0 Running On Ubuntu Linux 8.10

The next step for me is to install Windows on VirtualBox, but I'll have to try that another time.

Saturday, January 3, 2009

iPhone SDK is MacOS-only

I came across the iPhone SDK on the Apple website some time back, so I thought I'd finally go register and download it. It turns out that the iPhone SDK is only available for Mac OS X users but I only run Windows and Linux :-(

That is sooo unfair! I just bought an iPhone from them and now I have to buy their MacBook if I want to write free software and promote the iPhone?

Installing Ubuntu 8.10

For a while, I've been trying out Ubuntu 8.10 from the DVD without installing it to my hard disk and it seemed to be pretty stable. Today, I finally decided to take the leap.

I started off with 2 NTFS partitions that took up the entire hard disk space so I had to resize one of the NTFS partitions to get some space. I thought I'd use PowerQuest Partition Magic 8.0 from one of my really old CDs, but it didn't seem to recognize my 2nd NTFS partition. Perhaps Partition Magic 8 chokes on large partition sizes or something of the sort.

Anyway, I decided to give Ubuntu's resizer a shot. It worked quite well and my NTFS partitions are still fine, so I guess I'll be using it for all of my future installations.

Setting up wireless was a breeze! As soon as I logged in, Ubuntu displayed a bubble indicating it found some wireless networks so I entered my WEP key and I was connected in a few seconds. I had to do an "apt-get update" to refresh its lists before it could recognize the monodevelop package, which was pretty easy to install with "apt-get install monodevelop". I then used the GUI to upgrade some other packages. After getting accustomed with "apt-get", I don't really miss "yum". They're pretty much the same.

I'll probably post more about Ubuntu after I install some new stuff. Until then, do post a comment about your experience with Ubuntu 8.10 that you would like to share.

iPhone Upgraded to 2.2 and Locked!


I got a new iPhone last night, having switched from the iMate/HTC camp after about 3 years. Before going on an iMate/HTC shopping spree, I was a pretty big fan of Nokia's Communicator series.

The iPhone is SIM-unlocked as we don't have any cellular carriers in this part of the world that have a deal with Apple. The first thing I tried to do was figure out how to transfer stuff to the file through Bluetooth, but if you're an iPhone owner, you've probably already figured out that the Bluetooth support on the iPhone is limited to headsets so that's a major bummer. Who would ever imagine a smartphone that doesn't support Bluetooth transfers?

Anyway, that's how I went about pulling out the USB cable to transfer across my MP3s. As is the case with the iPod, you need iTunes (for a stock-iPhone) to copy multimedia content across.

The firmware was at v1.1.4 and as soon as I plugged it into iTunes, a popup message indicated a new update to v2.2. I upgraded and as soon as it was complete, I ended up with a SIM-locked phone. I noticed ZiPhone installed when I first got the iPhone so I tried to use ZiPhone 3.0 for the unlock, but that just hung at Entering Recovery Mode. Anyway, I'm going to try QuickPwn 2.2 on it.

Unlocking an iPhone isn't really illegal. It's a grey area because, unlike software piracy where you don't pay for the software, in this case you actually do pay Apple for the iPhone.

UPDATE: I managed to unlock the iPhone with QuickPwn 2.2.

Friday, January 2, 2009

What Does TSVNCache.exe Do?

TortoiseSVN installs the TSVNCache.exe file which runs in the background. It displays an icon overlay indicating the SVN status of a file. When a file is written to disk, TSVNCache checks to see if the folder containing the file contains a .svn folder.

If TSVNCache performs a lot of disk activity, you can select the folders that it listens on by going to TortoiseSVN -- Settings -- Icon Overlays, excluding the root of all your disk drives (make sure you add an "*" at the end), and including the folders containing your source code. You may need to restart for the change to take effect.

Alternatively, you can set the Status cache to None if you don't want the icons - this will turn off TSVNCache entirely.

You can use Filemon from SysInternal to check your mileage.

To get a tray icon for the cache, you can set the HKEY_CURRENT_USER\TortoiseSVN\CacheTrayIcon DWORD key to value 1.

XML Sitemap Maintenance Tool

A co-worker recently used a sitemap generator to come up with a few thousand URLs from our website with generated changefreq and priority. Now, these are going to take ages to go through and manually set the changefreq and priority for, so I thought we need to find something that can do a Find-and-Replace that can set the changefreq and priority if the loc (URL) matches a specific string.

This seemed to me a fairly common requirement, but I couldn't find anything through Google. I guess somebody (me!!) would have to build a tool.