21 Feb 2006

apache is dead! long live lighttpd!

after a two day delay over the weekend, as usual the album art widget release unleashes a huge amount of hits to my site from macupdate, apple and some japanese mac sites which i keep on discovering every month. this month it is mac.page.ne.jp, bringing a huge number of hits to my site. it actually has an interesting description of my widget (translated to english via rikai). maybe i should for a japanese translation of the widget some time to show off my bad japanese (どうぞ よろしくおねがいします~~). maybe i'll put in an easter egg in the next version if you have a japanese locale.

oh and talking about my widget, there's a german pdf that has an article about it. interesting because i got some pdf referrerals in my logs which i thought was odd!

anyway, back to the point of the post, the sudden surge of traffic last night killed apache. well, not exactly killed, i use apache as a frontend proxy to a lighttpd/fastcgi backend. and ever since i switched, performance hasn't improved that much, and in some instances, its even worse. i couldn't figure out a reason why, at first i thought it was my python fastcgi server (flup) on the other end. but after some tweaking and tuning, i realised the bottleneck was not there, but in apache. the version of apache i'm using seems to have a problem dealing with alot of proxy requests even with bumping the MaxServers variable quite high.

i had been holding off making the full switch to lighttpd because there are a number of domains hosted on the server i'm using, and some of them make use of features that aren't supported in lighttpd like .htaccess. so what i've done is made lighttpd the frontend server that does its best job serving static files and fastcgi, and relegating apache to a backend server where i proxy requests for domains that need php and .htaccess. with this way, i can slowly ween them off the addictive apache drug onto a more lean setup.

but i'm very glad i've put in the work to do this, now liquidx.net is super responsive compared to what it was like yesterday and the last 6 months.

... Read More


20 Feb 2006

newsvine : what the hell is it?

newsvine is one of these web 2.0 ventures i don't get. i just got an invite to it, so i decided to log in and try it out to see what the fuss is about, and why the hell is it in private beta behind some closed wall?

Newsvine

what did i find? nothing exciting. in fact, i don't even know how to explain it. let me have a go. imagine yahoo news with the AP articles and pictures, now imaging instead of that 10 star rating at the bottom, you have a very subtle digg like icon on the top of each story to vote on it. this promotes the story.

on the other side of the site, some people can write their on editorials (like a blog) on any news story or groups of story they see fancy. add a bit of social networking, commenting and collaborative filtering for good measure.

the final bit of newsvine is that you can submit stories (they called it "seed") to the queue that they can grab more content from other sources, thats just like submitting a story to digg or bookmarking something to delicious.

the problem i see is that the editorials that you can write are only available to the small community that are logged in, what is the point of writing it? so all in all, this is just digg with a nicer cleaner interface, a walled garden and no real purpose.

in short, don't bother logging in. you're not missing out on much at all.

if you were to try some news ranking aggregating site, you should check out meme-orandum. that uses an algorithm to fetch headlines from major blogs and news sources to determine what is hot, probably more closer to google news for tech than digg.

... Read More


20 Feb 2006

huge geocoding database from the us military

if you are looking for geocoding inside the US, then there are a huge number of resources you can use, most prominently yahoo's geocoding api and geocoder.us.

however, if you're looking for things outside of the US, things are a little more sparse. there are spots of ordinance surveys in various countries like australia and uk (which is what i'm interested in.) but i've recently come across the GEOnet name server that is maintained by the US military that has over 5 million place names in their database. basically they have names of cities, towns and districts with their proper latitude and longitude from everywhere in the world.

their tab delimited data file is over 760MB uncompressed. i'm planning to put some of this (criteria being places i've visited or want to know about) into a database so i can search it. for instance, i'd like to search for "killara, australia" and get the GPS coordinate for my suburb in sydney, or "happy valley, hong kong" and get where my old apartment is in hong kong.

been playing with webkit and google maps recently, and knocked up a little neat app that just does google maps. that explains why i was interested in if there were any good google maps implementations on the mac.

here's a quick screen shot of it in action:

Googlemapsapp

i have some plans to use it for something a little more useful than just browsing google maps for fun. its actually using the google maps v2 api so i get nice zoomed in features:

Cambridgemaps

a hint on what i'm planning to use it for, is why i'm suddenly so interested in plugin hacking and augmenting existing applications. will reveal more later when i actually accomplish it :)

... Read More


19 Feb 2006

circumventing ichat's g3 restriction (part 2)

Last week, I started a post about how I wanted to override ichat's restriction that prevented 600MHz or slower G3's from using any sort of video conferencing even though they are capable of doing it. So here is the second, and final part of that post that should you how to go about actually implementing a solution.

A quick recap on what we want to do. we've found out that we need to override either ProcessorSpeedMHz or [VCRules canSupportH264Decode]. What I found out later was that [VCRules canSupportH264Decode] doesn't help at all because it is only used on G4s.Tthe quickest way (probably not the safest way) to fool iChat into thinking we have a processor capable of doing video conferencing is to just report a fake result for ProcessorSpeedMHz.

Side Note: Overriding Objective-C methods



Replacing Objective-C methods and C functions are different.

For replacing Objective-C methods, all we really need to do is to modify the message lookup for Objective-C messages. This is done very easily using Method Swizzling. As usual, you need to determine whether you want to replace a class method or an instance method. But the idea is the same. There are a couple of good places for information about this on the net, which is CocoaDev and Mike Solomon's Cocoa Reverse Engineering wiki page.

To explain this quickly, what it involves is getting the selector for the original method and the replacement method, and calling class_getInstanceMethod() or class_getClassMethod() to grab a handle of the method you want to replace, and then just swap the method implementation pointers. In our case, if we were to replace [VCRules canSupportH264Decode], this is a class method, so our Method Swizzling function would look something like this (modified from the code in CocoaDev):


BOOL ClassMethodSwizzle(Class aClass, SEL orig_sel, SEL alt_sel)
{
Method orig_method = nil, alt_method = nil;

// First, look for the methods
orig_method = class_getClassMethod(aClass, orig_sel);
alt_method = class_getClassMethod(aClass, alt_sel);

// If both are found, swizzle them
if ((orig_method != nil) && (alt_method != nil))
{
char *temp1;
IMP temp2;

temp1 = orig_method->method_types;
orig_method->method_types = alt_method->method_types;
alt_method->method_types = temp1;

temp2 = orig_method->method_imp;
orig_method->method_imp = alt_method->method_imp;
alt_method->method_imp = temp2;
return YES;
}
return NO;
}


and you would invoke it in this way:


success = ClassMethodSwizzle([VCRules class],
@selector(canSupportH264Decode),
@selector(canSupportH264DecodeUnleashed));


where canSupportH264DecodeUnleashed is our custom function. You can call the original method also from your code, but counter-intuitively, you need to call it by the canSupportH264DecodeUnleashed selector because you've swapped them around.

For more information, I would encourage you to check out the Wiki page on CocoaDev for more information on Method Swizzling.

Step 3. Overriding C Functions in Mac OS X



Now, with C functions, things are a little different. C is not based on message passing like Objective C, you can't just go and swap the implementation pointers and pat yourself on the back. you have to do something more sinister. That evilness is called mach_override. mach_override is a part of the mach_star suite of tools that allow you to take control and inject code into other processes. It is really quite evil, but we're only going to use the mach_override bit and not mach_inject.

Note that this method only works on PowerPC at the moment, so if you have an Intel Mac, you're not going to be able to use this method. Developers are frantically looking for methods to emulate this hack, but I suspect it will be a while before you see this same technique resurfacing. Probably another reason (not) to get an Intel Mac if you don't want haxies working ;)

The idea is, if you have code running on the process already, you can swap out functions are runtime and replace them with your own. In our case, we want to override ProcessorSpeedMHz(), so we'll go ahead and use this method.

First thing you'll need to do is to download the mach_star bundle of joy, and copy over the mach_override.* files into your project. Now, we have to figure out how we want to use it. Do we want to call the original ProcessorSpeedMHz() at all, or do we just ignore it?

My approach is to ignore the original implementation, as that means less evil things to worry about like re-entering the overridden process. Since ProcessorSpeedMHz() is quite easy to write anyway, Apple has a sample implementation of a similar type of query but for processor type.

Therefore, we would just define our own ProcessorSpeedMHz() in the following way:


int ProcessorSpeedMHz();

int unleashedProcessorSpeedMHz()
{
OSErr err;
long speed;
err = Gestalt (gestaltProcClkSpeed, &speed );
if (err)
return 0;

if (speed < 600)
return 601;
return speed;
}


Nothing really special with this implementation here except that the output of Gestalt requires 8 bytes, so I assumed it wanted a long. We also make sure we have a reference to the internal ProcessorSpeedMHz function by just defining a pointer to it on the first line. All this function does is if the speed is less than 600, then make it 601, otherwise, just return the speed. This would make it work for all CPUs, even you kickass 2.0GHz in case you accidentally install it on those.

Swapping the functions out is a piece of cake with the mach_override tools, all we need is the following code:


mach_error_t err = mach_override_ptr((void *)&ProcessorSpeedMHz,
(void *)&unleashedProcessorSpeedMHz,
(void **)NULL);


All that is doing is swapping the implementation of the two functions. Once that is done, any further calls to ProcessorSpeedMHz will actually execute unleashedProcessorSpeedMHz.

Step 4. Getting that code loaded into iChat



So we have the mechanisms and the implementation to swap the function implementation, now we need to load our code into there. There are always more than one way of doing things. I've chosen on generic way of doing it, which is by using SIMBL. What SIMBL does is load itself into every process that gets started via the InputManager feature of Mac OS X, and then load a plugin that is registered for that application.

There are other ways of doing this, such as using Accessibility Features, writing your own InputManager loader, or even with some apps, they already have a plugin loading mechanism, so once you figure that out, you could inject your own code. However, the nice thing with SIMBL is that all that ugly evilness is taken care for you, and all you need to do is build your project as a Cocoa Bundle in Xcode and add this bit to your Info.plist:


<key>NSPrincipalClass</key>
<string>iChatUnleash</string>
<key>SIMBLTargetApplications</key>
<array>
<dict>
<key>BundleIdentifier</key>
<string>com.apple.iChat</string>
<key>MaxBundleVersion</key>
<string>429</string>
<key>MinBundleVersion</key>
<string>429</string>
</dict>
</array>


What that does is tell SIMBL to load your bundle only with an application identifier "com.apple.iChat", and for safety, only use it with iChat bundle version 429. You can find that out by just looking at the "About iChat .." menu item when the application is running.

Once you have you injecting code in there, and it compiles, you put it into ~/Library/Application Support/SIMBL/Plugins/ and SIMBL will do the hard work for you. Of course, you need to have it installed.

Finished



That's all there is to it. I'm putting up the Xcode project that does exactly what I've said here so you can have a play around with it. It will be available here called iChatUnleash. Use at your own risk, any sort of code injecting is pretty evil, but I suppose if you know what you're doing, you'll be alright.

... Read More


18 Feb 2006

what happened to the google maps widget?

does anyone know what happened to the old google maps widget from unobtrusive.org? the only available google maps widget online is some ugly non working version that fails to live up to the one that disappeared.

Googlemapswidget
guess which one is the new one and which one is the old one.

... Read More


18 Feb 2006

sweet charts in office 2007

i swear this is the only microsoft blog i[m subscribed to. but it's actually quite intereting seeing the changes that will take shape in the next version of microsoft's cash cow. this caught my eye recently because it reeks of web 2.0 style, but actually a very welcome change.

this is what default charts look like now in microsoft office:

 Msimages Defaultchartv11

and this is what it will look like in microsoft office 2007:

 Msimages Defaultchartv12

much much nicer, eh? of course i'm already thinking of whether that might be a nice add on to implement on canvasgraph after i do the svg port and integrate some long awaited changes submitted by users.

read more about them at jensen harris' office user interface blog.

... Read More


17 Feb 2006

album art widget 2.6 now with eyecandy

yes, my obligatory blog post about my little toy. album art widget 2.6 is out. only real change is fixing some critical bugs with intel mac support if you have non english tracks. this is related to my previous post about some apple bug on intel macs.

album art widget

the new eyecandy is just a slightly flashier icon. the old white icon just looked really ugly, probably the ugliest icon in my whole dashboard manager thing, so i decided i needed to change it. that's it folks.

... Read More


16 Feb 2006

NSString, Apple Events and Intel Macs

yesterday, i dropped by the london apple store to test something that had been broken on Intel Macs for the Album Art Widget, and also the EyeTunes framework. the port to universal was quite smooth as i had read through all the documentation and made sure that i didn't do anything that i had to do any byte swapping myself.

so imagine the surprise i had when i started getting bug reports about it not working on the intel mac. i scratched my head a couple of times and could see where the problem might be, but after reading and re-reading the unversal binary programming guidelines, i couldn't figure out what i had done wrong.

after some testing by commandeering one of the imacs, i put on some test programs to test Apple Events. these are basically what Apple Script uses under the hood. to cut the long story short, the bug appears that on Intel Macs, despite what Apple tells you in this paragraph in the Byte Swapping Strategies section:


Mac OS X manages system-defined Apple event data types for you, handling them appropriately for the currently executing code. You don't need to perform any special tasks. When the data that your application extracts from an Apple event is system-defined, the system swaps the data for you before giving the event to your application to process. You will want to treat system-defined data types from Apple events as native endian. Similarly, if you put native-endian data into an Apple event that you are sending, and it is a system-defined data type, the receiver will be able to interpret the data in its own native endian format.



emphasis is mine. i read that as any Apple Event type that was not defined by me, should be native endian, eg, on Intel Macs it would be Little Endian and PPC Macs, it would be Big Endian. WRONG! bzzzt.

it turns out that it is nearly true except for receiving typeUnicodeText (or 'utxt' for those who use the 4 character type codes apple loves). typeUnicodeText is basically a UniChar that is a 16 bite wide char value holding, you guessed it, unicode. turns out that the unicode inside is big endian regardless of architecture.

the kicker here is i then plug the values of this string into [NSString initWithBytes:length:encoding:], and use the NSUnicodeStringEncoding, it reads it in as UTF16-LE (little endian).

as far as i can see, NSString's interpretation is right. if you feed it what is allegedly UTF-16 without designating what byte order it is (eg. not using UTF-16LE mad UTF-16BE), then it should use whatever is the native byte order. even apple's own documentation later on about unicode text files in the same page explains this:

The constant typeUnicodeText indicates utxt text data, in native byte ordering format, with an optional BOM. This constant does not specify an explicit Unicode encoding or byte order definition.



so it should of extracted the text out in native byte ordering, not big endian. for those who want to see the code plus the workaround, here it is:


err = AEGetParamPtr(replyEvent, keyDirectObject, typeUnicodeText, &resultType,
replyValue, resultSize, &resultSize);
if (err != noErr) {
ETLog(@"Unable to get parameter of reply: %d", err);
goto cleanup_reply_and_tempstring;
}

// workaround unexpected big endian return valu
// alternative workaround would be to add the BOM for big endian in.
for (i = 0; i < resultSize/2; i++)
replyValue[i] = CFSwapInt16BigToHost(replyValue[i]);

replyString = [[[NSString alloc] initWithBytes:replyValue
length:resultSize
ncoding:NSUnicodeStringEncoding] autorelease];



although far from being definitive, this is what you get with python on a PPC machine:


>>> water = "\346\260\264"
>>> # water is the UTF-8 representation of the character "water" in chinese.
>>> water.decode('utf-8')
u'\u6c34'
>>> water.decode('utf-8').encode('utf-16')
'\xfe\xffl4'
>>> water.decode('utf-8').encode('utf-16le')
'4l'
>>> water.decode('utf-8').encode('utf-16be')
'l4'
>>> water.decode('utf-8').encode('utf-16be').decode('utf-16')
u'\u6c34'
>>> water.decode('utf-8').encode('utf-16le').decode('utf-16')
u'\u346c'


notice in python, if you do not specify the flavour of UTF-16, you will get the BOM in the front. that is the \xfe\xff you see in front of 'l4'. now, notice that i use UTF-16BE which strips out the BOM (correct again) and feed it back python's character set encoding. it will assume the native byte ordering (big endian on PPC) and output the correct UCS4 unicode character. the same one as what we started with. if we feed it the little endian version, of course it comes out wrong because the characters have been byte swapped.

now moving on to an intel linux machine:


>>> water = "\346\260\264"
>>> water.decode('utf-8')
u'\u6c34'
>>> water.decode('utf-8').encode('utf-16')
'\xff\xfe4l'
>>> water.decode('utf-8').encode('utf-16le').decode('utf-16')
u'\u6c34'


now note that this time, if we don't specify the BOM, python adds a different BOM to the front (\xff\xfe). this is the BOM for little endian. contrary to the previous example, it not specifying the flavour of UTF-16, python assumes UTF-16 in little endian (native endian) all the way.

so getting back to Apple Events, what the getEvent decoder should of been doing is to convert typeUnicodeText into the NATIVE ENDIAN UniChar * rather than just default to big endian. i don't know whether iTunes runs in rosetta or natively on Intel Macs, but either way, Apple Events should be converted properly and byte swapped properly as the documentation says.

final note, the creating an Apple Event Descriptor does not exhibit this bug. that is, if you send an Apple Event with typeUnicodeText and you give it a Little Endian Unicode string, the receiver on the other side of the Apple Event gets the right unicode string. So clearly this is a bug with Apple Events under intel macs. now i would file a radar bug report if only i was worth enough to do that. apparently worthiness is deemed by how much money you can chuck at apple to get an ADC select account.

... Read More


16 Feb 2006

hi velocity adsl provider (incompetent invoicing department)

i was customer of hi-velocity (hi-velocity.it) between december 2004 and august 2005. i chose that ADSL provider because at that time we did not have a one year lease on our flat, so we chose the one provider that would allow a short contract with a reasonable price. many other ISPs on the market were one year contracts only.

we never had much trouble with the service. note that even though their domain name is in italy, they are a UK ADSL provider! figure that one out.

anyway, ever since i moved out of that place and cancelled the service, they have been occassionally hassling me to pay them for a mysterious invoice that i never received. in fact, i had to do my own research to track down which invoice they hadn't sent me and were asking me to pay. they kept on insisting that i hadn't paid an invoice in july, even though i had. i was only after some investigation that i discovered i never received an invoice in may. subsequent contact with them regarding this have proved fruitless because they keep on insisting that i pay the same invoice twice. since then, they have been threatening that they'll unleash debt collectors on me because of their own incompetence.

to setup the story, here are the details. monthly fee is £23.99 for 2Mbps ADSL. i was disconnected on the 28th august 2005. here are the exchange of emails since my notice of cancellation on the 27th july 2005:


From: "James White" <----@hi-velocity.it>
To: "'Alastair Tse'" <----@cam.ac.uk>
Subject: RE: Cancellation of ADSL Service
Date: Wed, 3 Aug 2005 04:27:14 +0100

Dear Alaatair,

Cancellation has been requested.

I have attached your the invoices that need to be confirmed as paid.

Many Thanks,

James

[Attached are three invoices -- june, july and august.]


so i replied to this email saying:


From: Alastair Tse <---@cam.ac.uk>
To: James White <---@hi-velocity.it>
Subject: Re: Cancellation of ADSL Service
Date: Wed, 3 Aug 2005 10:29:28 +0100

Dear James,

I thought I had paid the June invoice already? It should have gone
through on 23rd June 2005. Could you please check this? I'll pay the
other the July and the August one immediately.

Thanks,

Alastair


i never receved a reply from this "James" about this query. in fact, thinking back, i had never received a reply from their accounts department every directly to my emails. so 10 days later, i get another email from them repeating that i hadn't paid. it is as though they have never read my email:


From: "Accounts" <----@hi-velocity.it>
To: <----@cam.ac.uk>
Subject: Hi-Velocity
Date: Fri, 12 Aug 2005 17:25:18 +0100

Dear Alasair,

Can u please confirm payment of your final invoice or invoices.

Many Thanks.


amazing, notice that they managed to spell my name incorrectly in both emails in a different way. what a feat! bravo!
of course, i replied and told them i had paid the ones that i know are outstanding:


From: Alastair Tse <---@cam.ac.uk>
To: Accounts <---@hi-velocity.it>
Date: Fri, 12 Aug 2005 17:27:54 +0100

Hi,

I have paid the invoices on 3-4 August.

Cheers,

Alastair


notice that i replied to them within two minutes of receiving their email. imagine the surprise i when i receive an email on the 27th of september, a full month after i had disconnected from their service and 2 months after i had sent the first email asking them to clarify which invoices i hadn't paid:


From: "Accounts" <----@hi-velocity.it>
To: <----@cam.ac.uk>
Subject: Urgent Confirmation Required
Date: Tue, 27 Sep 2005 16:07:27 +0100

Dear Alasair,

Can you please confirm payment of your outstanding £47.98 on your
account.

This is very urgent so your prompt response would be appreciated, please
note that failure to reply may resolve in legal action being taken to
recover monies owed to us.

I look forward to hearing from you.

Many Thanks,

Invoicing Department
Accounts
Tel: 0870 770 6919
Fax: 0207 231 6444


imagine the surprise i had when i saw this email saying that i had owed them nearly double of what they claim i owed them previously. i immediately replied asking for clarification:


From: Alastair Tse <---@cam.ac.uk>
To: Accounts <---@hi-velocity.it>
Subject: Re: Urgent Confirmation Required
Date: Tue, 27 Sep 2005 16:29:45 +0100

Hi,

I've responded to this before. I have paid the balance of the account
2 months ago. If you have any problems, I need you to tell me which
particular payments you have received and which bills you think I
haven't paid so I can verify.

Thanks,

Alastair


shortly after, they send a clarification email saying they made a mistake, in fact i owe them £23.99 instead:


From: "Accounts" <----@hi-velocity.it>
To: <----@cam.ac.uk>
Subject: Urgent Confirmation Required
Date: Tue, 27 Sep 2005 16:07:27 +0100

Dear Alasair,

Please ignore the previous email sent to you.

I can confirm that your July invoice for £23.99 is the only invoice
outstanding.

Can you please confirm payment.

Many thanks.

Invoicing Department
Accounts
Tel: 0870 770 6919
Fax: 0207 231 6444


alright, so they have their head screwed on correctly today. annoyed by their persistant vagueness of the claim that i own them some money, i spent half an hour going through the my emails digging out which emails i had and also going through my online banking account to confirm the payments, something that they should have done rather than me. nevertheless, i thought this would help their incompetent staff figure out what they really needed to send me so i can pay it. i'm not going to pay twice for the same invoice:


From: Alastair Tse <---@cam.ac.uk>
To: Accounts <---@hi-velocity.it>
Subject: Re: Email sent in error
Date: Tue, 27 Sep 2005 16:47:45 +0100

Hi,

I've just been through my records, and I've realised what has
happened and why you claim that I have not paid the July invoice when
I did so on 3rd August.

I've gone through my emails and discovered that I never received the
invoice for May.

According to my records I've received and paid for the following
invoices:

23 Feb: Received 3 invoices for (December, January, February)
02 Mar: Paid 3 invoices December, January and February
10 Mar: Recieved March Invoice
15 Mar: Paid March Invoice
15 Apr: Received April Invoice
03 May: Paid April Invoice
08 Jun: Received June Invoice
23 Jun: Paid June Invoice
06 Jul: Received July Invoice
03 Aug: Received June, July and Part August Invoice Again
03 Aug: Paid July and Part August Invoice

So there seems to be an invoice missing which I don't have and I
didn't realise was missing. So I guess the best way to settle this is
that you send me the May invoice again so I have it on my records and
I will pay that.

Cheers,

Alastair


i thought i made myself pretty clear there what had been paid and what i never been billed for. i didn't receive the invoice for the month of may so i never paid it. i hadn't even realised this omission since i just pay the invoices as they come in, only when i looked back through my records did i discover that there was an invoice missing.

after i sent this email, there was no reply. no legal action. no nothing. i couldn't just pay them without having an invoice, that would of been wrong on my counts. they never emailed me back with the right invoice and so i thought they realised their mistake and were so sorry that they would give me one month free.

only i was wrong because today i received an email, more than 4 months later that apparently they going to unleash a can of whoop ass on my with debt collectors:


From: "Accounts" <----@hi-velocity.it>
To: <----@cam.ac.uk>
Subject: Hi-Velocity - Outstanding Invoices
Date: Tue, 14 Feb 2006 12:19:52 -0000

Dear Sir/Madam,

Can you please confirm payment of the attached outstanding invoice(s) as a
matter of urgency.

If we do not receive confirmation this account will be passed to our Debt
Collections Agency.

Please contact us as soon as possible.

Many Thanks,

[Attached was the July invoice]


so their valentine's day present to me was to give me a threatening email -- note that i have be demoted from the misspelt "alasair" to sir/madam. i suppose its an improvement as they spelt that right. i was so amused by the fact that it was a MATTER OF URGENCY that i replied immediately. in fact, it has been so urgent that they have been sitting on this for nearly 6 months since i disconnected from their service. here's my reply:


From: Alastair Tse <---@cam.ac.uk>
To: Accounts <---@hi-velocity.it>
Subject: Re: Hi-Velocity - Outstanding Invoices
Date: Tue, 14 Feb 2006 12:37:08 +0000

Dear Hi Velocity.

Just to be clear in case I get another email 2 months down the road
that tells me I haven't paid something that I was never asked to pay
(half a year ago). How many invoices should be in this email and for
what dates?

I find it amusing that you state this as a "matter of urgency", yet
it took Hi Velocity 6 months to actually send me an outstanding
invoice. As I wrote in an email on the 27th September 2005 with the
subject "Re: Emails send in error", I had listed the invoices that I
had paid and the ones I had never received. If you acted on that
email back in September, you would have got your payment immediately
then, so why threaten me now.

Please note, in my email I listed all the invoices I had received and
paid for, and in that list I had paid for the July invoice that is
attached in this email. Please verify which invoices you haven't sent
carefully and send me the correct one. Once I get that I will pay it
immediately. To be clear, that is the one that was never sent to me
for May.

If you need me to send in all the PDFs or the invoice numbers that I
have received, please let me know as I would be happy to oblige.

Below is also a list that I am copying from my previous email back on
the 27th September of the invoices that I have already paid and the
one invoice I never received but only alerted to after I received a
previous threatening email 5 months ago.

Regards,

Alastair Tse

[Attached was the email I sent on 27th September detailing what I had
paid and what I had received]


i don't expect them to reply to his email as they haven't done with the last 4 i have sent them. it is funny how easy it is for them to get my money, they just have to send me the right invoice with a different number than all the previous ones they sent me. yet they just insist on sending me the same one over and over again.

i'll post more updates as this happens. in short, don't do business with hi-velocity until they sort out their billing department. hope this is as amusing to me as it is to you. i'm also hoping that enough people will read this and enough bots will read this that google will start to index this near to top of the hits when you search for hi velocity.

... Read More


14 Feb 2006

new naming scheme for things on the net

here are the rules to follow:

1. add an "r" to your name even if you don't need it and if your name already has an r, remove the vowel before it.

examples: zooomr, frappr, suprglu, feedblendr, gtalkr, browsr, flagr, wrickr

2. add dots randomly in your name so that people think you ge.t it. (aka. i've heard about your but for the life of me i can't get to your domain, goddamit) extra points for ending with .us.

examples: mag.nolia, imp.etuo.us, porn.a.licio.us, script.aculous, last.fm

3. append random number in front of your name:

examples: 43things, 9rules, 30boxes, 37signals.

4. finally, make sure people have no idea what you do by just your name:

examples: eskobo, pandora, wuraweb, joyent, blish, oyogi, gravee, platial, shozu, spongecell .. there are too many to link to, i can't be bothered to be turned into a link farm.

of course, there are the originals who started these rules, flickr and deli.cio.us. but we'll let them off this time.

for more web2.0 insanity, check out this company list from techcrunch.

... Read More