Tuesday, April 28, 2009

The iPod Touch is awesome

Yes,i finally gave in and got my first iPod. First i must say, that although i still hate iPhones, when it comes it MP3 players this thing is awesome.

Messenging devices need keyboards.

For all intends and purposes this thing is basically a netbook/net tablet.

China (and my dissertation!) is only days away. All i'm lacking now is the camera. 

** UPDATE **
Never edited a blog post in my life, but there is first time for everything, and this perfectly illustrates my point.

This post was short for a reason. I wrote it on a ipod touch. I hate typing on touch screens, i like keyboards. Why you ask? Tactile feedback! A simple beep is great, but imagine, if you could actually press a key, and feel the response from it! Wouldn't that be awesome! RIMM thought the same thing, and created the Storm, sadly RIMM should have stolen a page from Palm, and took a handful of Apple engineers to create the UI. Cause the Storm sucks badly (plus no Wifi what year did you think it was!)

Virtual keyboards not only provide no tactile feedback, but they also take up screen real estate. Granted that in most situations you only need it for a couple of seconds to put in a web address or to send a tweet. If you are from the long form generation, and can see past the reality distortion field (no physical keyboard eliminates the need for multiple skus!! ), you will know that keyboards are just better. Thats why i'm clinging to my e61 with a death grip, it's huge, ugly, but it messages like no other (well until palm pre time!).

Tuesday, April 21, 2009

中國 is calling


I decided to blog from the park today. The primary reason behind this the 18 degree weather. You have to take advantage of this things when you have the chance.

In all the time i've had my beloved blackbook, i've never really used it outside. Quite frankly i don't know why. It looks quite cool(i think) to just sit here, with google reader watching the news and the world go by all at the same time.

At the moment there are two things dominating my mind, well actually three, but i'm only going to write about two.

China,
I'm getting so excited it's scary. Currently i'm waiting to see if the lovely folks in the chinese government will grant me entry to their beautiful county. I'm practicing my chinese often, and my tonal pronunciation is getting better.
I still haven't decided whether or not to bring my mac. I didn't want to, but i planned to have a palm pre in my possession by this time! But if i really want to podcast, and stay fairly connect, and considering that my e61's battery doesn't hold a charge like it used to it maybe that time. Plus i get to play FM for hours, oh the fun i'm gonna have! Just imagine a 22 year old man clapping to a screen at 40k feet!

My degree,
It's almost over i can taste the end, and it tastes sweet. Not quite 草莓 (Strawberry)but nice. There is still a fair bit of work left to do, but all things are possible, and i'm on target. Sadly i doubt i'm going to get a stunning degree, but at this point i just want to be free of academia. But at the time of writing there are only another 2 and bit weeks left, so bring it on. (remind me i said that).

With summer coming up, and hopefully more time on my hands i'll hopefully blog a bit more. It's not like i'm going to be doing loads now that i 'have' to hold down a job, but still if people can have 100k followers on twitter i surely must be able to blog once a week. Maybe i need to but some twiiter integration on this thing! Speaking of integration, The usual summer process of redsign should be happening soon, both the blog and the company site, i need to attempt to be serious, if only for a moment.

再見

Quote of the Day
"The greatest skill you can have as a man is being able to cook"

Mark Udall, One of my lectures

Friday, April 10, 2009

Couch DB as messaging queue

Never thought about it before, but the idea ran through my head while writing my dissertation. Thought i should save it for a rainy day. But it would make a very nice queue. 

Ah, Messaging queues so distinctly british!

Thursday, April 02, 2009

Beijing Bitches

It's booked i fly out on the May10th

My route is:

Beijing > Shanghai > Xi'an > Yichang > Three Gorges Dam > Yangshuo > Hong Kong

I've even started a podcast. The Only Negro In China Podcast. I recorded the first episode yesterday, expect to see it online soon.

Exciting times

Thursday, March 19, 2009

I need to try this

We called it the Rubber Duck method of debugging. It goes like this:

1) Beg, borrow, steal, buy, fabricate or otherwise obtain a rubber duck
(bathtub variety)
2) Place rubber duck on desk and inform it you are just going to go over
some code with it, if that's all right.
3) Explain to the duck what you code is supposed to do, and then go into
detail and explain things line by line
4) At some point you will tell the duck what you are doing next and then
realise that that is not in fact what you are actually doing. The duck
will sit there serenely, happy in the knowledge that it has helped you
on your way.

Works every time. Actually, if you don't have a rubber duck you could at
a pinch ask a fellow programmer or engineer to sit in.

Andy

Andrew Errington src

Tuesday, March 17, 2009

So thats why Java ME is so popular

I have to hand in my EWT (Emerging Web Tech) assignment tomorrow.

Part of the assessment is a look at Development platforms in the mobile space. Until recently native was a dirty word as it usually involved device specific C code. Java has always been fairly popular, but i've always dismissed it for it's non native look and feel.

However, after exploring java ME some more i can see why it appeals to many developers.

The Hello world application is fairly simplistic compared to iPhone, Andriod and especially symbian equivalents.

But we all know that it doesn't hold a candle to the Palm Pre. I would demostrate how amazing the Palm Pre is, however i don't have one yet!

Now if i could just work out how to install the thing in OSX we might be on to a winner!

Lastly the 3 iteration of the iPhone SDK was released today. It's good to see apple can still pull some magic out of the hat. I call it magic, because only in the world of apple can cut and paste be termed as a feature on a smartphone in 2009. FYI i've been cutting and pasting on my E61 for 2 years!

Monday, February 23, 2009

Disseration 101: spanning data across multiple cookies

Cookies have are spec'd to hold a max of 4KB. Thats a lot of data. 4096 ascii characters to be exact. However this is 2009, and my ideas of 'a lot' are laughable. Well since we know that one cookie holds x, how about 2x?

Well thats great, but how do i split data across two structures, and ensure that it remains consistent. Well clearly this problem isn't new, it's been solved in TCP, RAID, and many other situations.

TCP's approach is to assign each segment a sequence number, it divides the load based on the window size and assigns it a number.

But how would that look?
(key:value)
foo=1007; hello
bar=1007; world

the issue with the above is that i have to access random keys to get at the data, so something like the below would be better ...

x1007=foo: hello
x1008=foo; world.

in the above the name of the cookie is the sequence number, the first value is the name of the user key, and following the semicolon, the value. Still a little rough around the edges, but what isn't?

Another alternative, is to cram as much data into each cookie. This increases the amount of entries that could be assign

Friday, February 20, 2009

Foreign living

My trip to Barcelona has been fasinating so far. One of best moments was visiting a local supermarket. It was amazing to be surrounded by people, who all spoke another tongue. It was amazing to have a convrsation with someone else, knowing that everyone (or at least most people), had no idea of what was being said.
It made me really want to live and work outside of uk. i've always felt that i don't want to raise my children in britian, for variety of reasons. So it seems logical that i try to move aboard, but the question is where do i start?

Friday, February 06, 2009

hola! Barcelona

I'm on my way to barcelona at the moment. Its perfect timing really as the weather this week has been crap. So 3 days in relative sunshine should be nice.

Wednesday, February 04, 2009

Jonathan and the social internet revolution

It's 2009. I forget this a lot of the time and find myself doing things circa '00.

Well as of today, no longer. Twittering, flickr posting, facebook ... Stuff (surprisingly doesn't have a verb yet), i should be doing it all.

I won't go as far as to say that the days of isolation are over, however when i find myself giving away my location (using googles new latitude service), you can see why i think this way.

i really want a new phone

Sadly in the mean time, i'll have to deal with just having this (e61) thing. I had planned to get the nokia e71 again however, the palm pre happened. At which point all my funds went right back into my pocket. This isn't a blog post of sorts, just an opportunity to test out blogging from a phone, via email. I was working on a blogger client using python for s60 however, i've just remembered how much fun mobile development is without a decent emulator.

Wow, thats old

Considering that this is the internet and all, i thought i should post this. below was the old text from the about me section of this very blog.
Russian Space Station, named in partial memory of the Fallen "Mir" and that outpost from the movie "Armageddon". I talk about technology, my new life at Southampton Solent University and living on my own @ 18. Subscribe on the RSS or just visit, thanks for popping by.


Tad out of date don't you think.

Are men really that useless: Anglerfish reproduction...

I've always been told that men are useless, however this takes the biscuit. This is how anglerfish reproduce

When he finds a female, he bites into her skin, and releases an enzyme that digests the skin of his mouth and her body, fusing the pair down to the blood-vessel level. The male then atrophies into nothing more than a pair of gonads, which releases sperm in response to hormones in the female's bloodstream indicating egg release.

Sadly i know men who are about as useful as this...
Source

Anyways I'm gonna try and liven up the blog, one post a month/2 months is crazy, this is web 2.0 right. Daily journal returns ...

Quote of the Day
Josh "After i'm done swiping my visa, I'm gonna ask them what their flavour is?"
Me "What do you take this thing for, Baskin Robins!"

Grown women taking their clothes off, seems to have a strange impact on people.

Wednesday, December 31, 2008

2008: The Year in Review

In keeping with RSS tradition, i felt that it was only right to look back at the year. Review my highs and lows, my victories and failures, and highlight anything else that took my fancy during 2008.

My highs of 2008

FOWA London 08
My first tech conference. It was a great experience. I met a lot of people that i would never have met otherwise. It also gave my twitter account a reason to exist. However, the best part of it was being surrounded by other people that knew what i meant when i said something, and more to the point, said things that went completely over my head. Part of me would like to go to the miami event, however not sure if i can slip it in given my workload.

Netro 42
Having been locked up as ASP programmer, i have to thank the folks at Netro42 for letting me break my professional PHP duck. However thats not the only reason that i enjoy it, it also gave me a chance to work with a smaller (not quite startup) company, and see what that is like. Best of all i got the job via facebook!

The return of a friend
One of my best friends had changed over the summer of 2007. Don't quite know how to describe it, but they were different. Anyway, when they returned to uni in 08 they had returned to their old self. It was like getting a whole new friend.

A New friend
Sure i met loads of people during the course of 2008. However some stick out more than most. This year that person was Yasmin. Don't know why, but we just get along really well. Like my other friends i'm blessed to be able to meet nice people.

Fulham/ Jimmy Bullard and Roy Hodgson
Amazing, simply amazing.

Working with Non-Brits
Thanks to FOWA, i got to work some nice guys from holland. Unfortunately our project, an iPhone application hit a snag, and won't be rolling out anytime soon. But it was one of my long term aims. I'm now really considering moving abroad to work.

Chinese Speaking
Ni Hao, wo shou zhongwen! Never thought that would happen, but it did in 08.


My Lows of 2008

Amit going home
This was a sad moment, just because he had been a constant character while i've been at Uni. Part of me felt responsible for not trying to help him more. But hopefully his absence won't be the end of our association.

Looking for work
This sucked. Full stop it sucks, ultimately it had a positive outcome. But during the search it sucked.

Wanting to leave uni
After returning from the summer break, i felt that uni had run it's course. Having tasted the big bad world, i wanted more. Maybe it was the paycheques going to my head, or maybe it was something else. But after moping around, and being told i'm a fool by most people i decided to stay, and look i'm writing this post now ^_^.

Some of my standout moments of 2008
  • Tunde smashing a window when manchester united won the champions league.
  • Quickly followed by a random guy dancing and screaming in our house.
  • Being mistaken for a homeless person
  • Helping Joel home after a messy evening envolving a bottle of rum
  • Meeting Lorenzo Barbosa
  • Working on the Kings Road, Ahem, Chelsea Ahem, West London Ahem.
  • Spending £80 on a coat, never thought i would see the day
  • Not buying a single piece of tech this year, although not without trying (thanks expansys).

Overall 2008 has been good to me, the lord has been good to me. Despite my attempts to mess things up via over thinking, and who knows what else, i'm still alive and well.

Targets for 2009
  • Travel
  • Go to China/Hong Kong
  • Start making some damn software already
  • Be slightly less boring (seriously)
  • Get closer to God
  • Learn another language
  • Read more
  • Speak my mind more
How many legs does a dog have if you call his tail a leg?' The answer: `Four, because calling a tail a leg does not make it a leg'
One of Abraham Lincoln's favorite riddles

I love high brow quotes as much as the next guy, but it wouldn't be the same without some of my favourites from the year...

"Chamonsters" - Yasmin
"All Right, Dear Diary, Jackpot" - Family Guy, Tunde, Josh, Jai
"Wee Ooh Wee Ooh Wee" - Lil Wayne, Ms. Officer
"Manage Expectations" - Any office anywhere
""


Tuesday, November 18, 2008

Objective-j is amazing

I got bored in the library today, so I decided to check out objective-j. In a word Amazing. It's objective C in the browser, not like it, it is actually it, down to the @at the declaration of a string.

Unfortunately I've got nothing to take advantage of it at the moment, maybe in the summer/ rest of my life

Sunday, November 16, 2008

Javascript client storage library

So thats my dissertation topic. It's out there for the world to see. Up until very recently it was GIT GUI client, however after checking out GIT GUI my ideas seemed redundant, and wasteful.

So the plan is to develop a client side storage wrapper/ abstraction independent of any of the major is frameworks. Light weight wrappers can then be built modeled on the singleton pattern, for the various libraries. The library would have a "storage provider" interface , therefore as technologies are introduced new providers can be created. Initially I plan to create 3. Cookies, flash, & HTML 5 session storage.

As I'm typing this on a iPhone, I'll stop now. But rest assured I hate this thing.

Monday, November 10, 2008

IPhone livin

My brother was kind enough to lend me an iPhone.

At the moment it's just to test out my new iphone app. But I really don't think that apple will be seeing my cash on this front. As I learnt with my palm, touch screen keyboards dont compare to regular qwerty ones. Sure you narrow skus, but the difference in typing speed is to much for me.

I will say that the interface is just as amazing as it looks. But this thing still needs some work

Sunday, November 09, 2008

Jonathan, The stock broker

First of this crap is gambling, don't let anyone tell you any better. With all the flashy screens and graphs you may think it's not, but when you really think about it, thats what it is.

My inspiration was Warren Buffett, he said

Be fearful when others are greedy, and be greedy when others are fearful


Greed is what ruins anyone, control the greed and the success will come (in theory). So first your wondering where did i get the cash from, well i had planned on buying a new laptop, but it didn't really make sense. So instead of just handing over the cash to apple, why not try to do some proper investing.

I'm a firm believer in not trying to be too clever, there is only one sector i really know anything about, Technology. I planned to do a mixture of short term buys combined with some long term investments.

Sensible Investments
Apple or AAPL was one of my long term buys. Currently trading at sub $100 only a few months ago this stock was floating around $200. The company has low debt, and good sales, so it sells itself.

Sun or JAVA is a little more of a risk, the stock is trading low at the minute, mainly because of the credit crunch (read: can't borrow cash to buy servers), so there is a fair chance we might see an upturn in the next few months.

Crazy Ones
Lehman Brothers LEHMQ, first your thinking, but they went belly up. Yeah, they did, and there stock is trading at $0.067. Tempting ....

AIG, This is a stock that at one point as $70 it's now $2. What's the worst that could happen? But seriously, they have over a Trillion dollars in assets, and their stock is in the tank thanks to losing $8 billion in the last quarter.

RBS, This is an example of the fact that i actually know nothing. I picked RBS in my google finance portfolio about two weeks ago. at the time it was £0.90. At the moment it's £0.64, i lost 28%! Theoretically! Dangerous game this

One Day
Berkshire Hathaway BRK.A. The company of the great Warren Buffett, it's 1.55 million shares trade at $113,000 each!!! Just a tad out of my league.

Basically this stock thing is crazy, extremely risky and a money pit, but i can't wait to get my hands dirty (not in an Enron way!).

Good luck to any fellow investors.

Wednesday, October 15, 2008

When did it get this bad?

When did it get this bad? Just as well i'm Jamaican

Quote of the Day
Simon: What you getting?
Me: An iPhone, worst thing is i don't even want it

Damn Apple and closed market tactics

Monday, October 13, 2008

FOWA: My thoughts

FOWA was actually amazing. I highly recommend it to anyone who, like myself doesn't have a hardcore programming team to socialize with. One of the key benefits for me was meeting other people, the talks were good, but the networking was better.

Francisco Tolmasky
My highlight was getting to talk to Francisco Tolmasky. He is part of the team behind 280 north, popularized for its 280 slides app, and for bring Cocoa to the web. It was fantastic to talk to someone, who is trying to take the future of the web in a particular direction, and having the opportunity to understand that vision first hand, and be able to interact with them.
Plus it was a chance to talk to a not only a (former) member of Apple's development team, but also to man who's work can be found in many pockets, far and wide, as he was part of the mobile Safari development team.
Perhaps the most interesting thing for me was discovering that he was actually head hunted by apple. He had submitted patches to Webkit, and seems that the overlord was watching and gave him a call.

Jason Calacanis
I also got say hello to Jason Calacanis. He gave an insightful talk into his hiring philosophy. Essentially he advocated dumping average performers, and employing only good and excellent staff, arguing that there work output is significantly better than that of a mixture of average and below par employees.
I partly agree, however from a emotional stand point i think i would have a issue with sacking folks just because they're not amazing, however it could be argued that i wouldn't have employed them in the first place. My theory is that unless your smarter than me, it's not gonna work out.

Live Diggnation
Alex Albrecht is actually really funny in person. I never realized just how funny he is until the diggnation taping. His timing is fantastic.
Personally i'm not the biggest fan of Diggnation, however it was fun, i certainly wasn't screaming and diving around for prizes, but it was good fun.

Adobe Air
When i had first heard about this i thought it was gonna be amazing. However the need to install the framework put me off. However adobe has discovered that no one wants yet another shockwave/flash/sliverlight situation, and you can now bundle the framework with your app. I spoke to nice guy at the conf who explained to me all the cool stuff i could do, and answered all my questions. Air looks like a serious competitor to traditional (does a traditional web app exist?) web apps. The ability to run offline, and completely independent of the browser is temping, a great use is for forms in corporate setups, (read oracle forms and it's siblings are dead). Look out for some air apps in the future, however first i gotta work out how to get the application.xml file to work correctly!

New Project(s)
One of the main reasons i wanted to go to FOWA, was to borden my horizons, and thanks to my new dutch friends i did just that. I've been commissioned to make a small iphone app. This is ideal as i wanted to do some work with the iphone, but i had no iphone, and no ideas.
Since i get to do some iphone work, and i'm not really scared nor care for apples legal team, i'll try to publish some samples as i explore the SDK.

Macs and more Macs
I knew that macs where popular among my kind, but damn! There were too many, i almost felt sick. I would have loved to see a photo of what the audience looked like from the stage, it would have just been a sea of apple logos. On the note of Mac laptops, the new ones come out tomorrow, i think i might have to drop a G ...

All in all FOWA was great, I'm tempted to go to the one in miami in Feb 09, however the whole idea of a conference in miami doesn't really seem like work. Plus i'm a third year now, i can't be flying around the world 'networking' ... can i???



Ignacio: To follow a testing methodology?
Me: Nah, not really.
This is why it is important to go to conferences!

Saturday, August 09, 2008

Getting the file size before upload with Ajax

One of my new projects requires users to upload pictures to our service. The problem is that everybody and their mother has a 7.2 Mpx camera. After some wikipedia research i discovered that jpeg photos are encoded at maximum of about 8.25 bits/pixel. (don't write me about decimal point bit values please :) ).

So out came the pad of paper (and calculator)...

(7.2 * 10^6) * 8.25 = 594 * 10^5 [bits]

(594 * 10^5)/8 = 7425000 bytes or 7.1 Mb per picture

Now i wanted to limit the users to 1 Mb per picture, and wanted them to upload numerous ones at that. Now from a usability point of view it would be a "epic fail" if uncle Roy waited for 5 minutes while his picture uploaded, just to discover that we won't accept it because it's too big.

Now, I imagine your saying that this problem has been solved, it's called a flash uploader (or sliverlight depending on who you get your checks from). However there is a new solution, doing file size checking without flash, using only ajax.


Thats right ma, no flash. Firefox 3 has introduced something new to our world. It's called the filelist Object. Lying deep within in it is a property called (drum roll please) fileSize, and you can use it like so...


Javascript

//Only works in firefox 3
//i Used jquery to do a dom lookup
//However you could do the ol' fashioned window.document.getElementById()
fileSize = $('#fileInput')[0].files[0].fileSize;


It returns the size of file in bytes as an integer! 

Hopefully you've learnt something new, i certainly did. I have a plan to get a similar technique to work on all browsers, however at the moment i'm being thwarted by browser security issues :(.

You can get all the files over at the lab

Andrew Carnegie
A man who dies rich, is a man who dies shamed

Wednesday, July 23, 2008

OSS: Python webpage link checker

Another piece of python to go. Nothing special, but something fairly useful that i've thrown together. 
The following code samples are released under the terms of the GPL 2.0

It's URL link checker, it's not fully recursive (working on it, they don't teach recursive algorithms on my course). But checks all the anchor tags on the given page, returning warnings and the like depending on what it finds.

Usage: To use this just run it like so "python [scriptname]"
It will then ask for the url of the page you wish to check, and then it will print a report, like so.

Python

#Link Checker
#Brazen attempt to write one in 15 minutes
# Jonathan Dalrymple
# July 15,2008
# Start 11:52
# End 12:35

import httplib
import sgmllib
import re

#HTML Parser
class LinkChecker( sgmllib.SGMLParser ):
def __init__(self, verbose = 0):
sgmllib.SGMLParser.__init__( self, verbose )

self.linkList = []
self.inLink = False
self.lastHref = None
self.hostName = None

print 'Parsing file...'

def parse( self, fileStr ):
self.feed( fileStr )
self.close()

def start_a( self, attr ):

#Show user that the parser is working
#print '*'

self.inLink = True

for name, val in attr:
if name == 'href':
self.lastHref = val

def end_a( self):
self.inLink = False

def handle_data(self, str):

if self.inLink:

tmp = self.__parseUrl( self.lastHref )
self.linkList.append( (str,tmp['host'],tmp['path']) )

def __parseUrl( self, str ):
ret = {}

#slice of preceeding http
#if str[0:7] == 'http://':
# str = str[7:len(str)]

# Extract path regex "\w+\.(\w*)\.(\w{2}\.)?(\w{2,3})"
m = re.compile("\w+\.(\w*)\.(\w{2}\.)?(\w{2,3})").match( str )

if m == None:
#print 'Error in handle url, regex failed'

ret['host'] = None
ret['path'] = str
else:
ret['host'] = m.string[0:m.end()]

if m.end() <>
ret['path'] = str[ m.end(): len(str) ]
else:
ret['path'] = None

return ret
#Check link
def __checkLink( self, displayName, host = None, path = '/' ):
if host == None:
host = self.hostName

#slice path and determine if it is a full url
reqObj = httplib.HTTPConnection( host, 80 )

#print '---Requesting %s' % url+path
reqObj.request('get', path )

response = reqObj.getresponse()

if response.status == 200:
retVal = "SUCCESS |%s returned %d" % (displayName, response.status )
elif response.status == 404:
retVal = "FAILURE |%s returned %d, (%s)" % (displayName, response.status, path )
else:
retVal = "WARNING |%s returned %d, (%s)" % (displayName, response.status, path )

return retVal
def testUrlParser( self, list ):
for u in list:
print '--' + str(self.__parseUrl( u ))
def runReport( self, urlStr ):
urlDict = self.__parseUrl( urlStr )

if urlDict != None:
self.hostName = urlDict['host']
req = httplib.HTTPConnection(urlDict['host'], 80)

req.request('get',urlDict['path'])
response = req.getresponse()

if response.status == 200:

htmlStr = response.read()

self.parse( htmlStr )

print "%d links found" % len( self.linkList )

for v in self.linkList:
#print v
print self.__checkLink( v[0], v[1], v[2] )
else:
print "Download Request for %s failed: %d" % ( response.reason, response.status)


def main():

#urlStr = "http://www.google.co.uk/search?hl=en&q=bar&btnG=Google+Search&meta="
urlStr = raw_input('Url you wish to check:')
if urlStr != None:
bar = LinkChecker()
#foo = ('www.google.com','http://www.google.com','http://docs.python.org/lib/lib.html','docs.python.org/test')
#bar.testUrlParser( foo )
bar.runReport( urlStr )

if __name__ == '__main__':
main()


Quote of the Day
I now finally understand why those guys buy £100,000  cars, only to sit in traffic. It's because they remember the days of running for the train, only to find that it's standing room only and their new best friend is a significantly taller gentleman's (or lady!!) armpit and or sweaty back.

Realizations, Andorra here i come

Thursday, July 17, 2008

20 hours, count it if you haven't got anything better do.

In a few months i'll be going to china. I'm led to believe the fight is like 20 hours, making it the longest of my life. I honestly have no clue what to do in that time. A second battery for the macbook is essential, however beyond that what do i do! Count clouds, see if i can work out where i am, sleep...

On another front, i got a job or contract i should say. Working for netro42 in london. I must say i love it there for a number of reasons.
A. I have a 4 core mac pro and 23" cinema display
B. I get to use osx to work
C. They have flexible working times ie 10am is just fine with them.
D. The office design is ultra modern and open plan.
E. Management are the development team!!!!
F. The people aren't too bad either.

There are a lot of lessons which i plan to take out of this and apply to my own company once i'm free of uni. But its been a good experience thus far.
Quote of the Day

Caption

Saturday, June 21, 2008

Facebook Chat

This started as a long post, but as i am learning actions speak louder than words

Monday, May 19, 2008

Backrow, Thats a big ass framework

Some months a ago i spoke about front row. First, the plan was to reverse engineering it, then it was building a plugin for it. Well, it hasn't exactly had my complete attention, however it did drift back into my mind today.

The main sticking point for me has been the lack of documenation, however this should be expected considering that we're talking about a unsupported framework, from one of the most secretive corporate entities in existance.

So in my quest to write for leopard front row, i decided that a nice class diagram would come in handy, easy right...

Well this is what it looks like, after exploring appoximately 30-40% of the 500+ classes!

However i've learnt alot about naming conventions and framework layout. The most striking thing is the level of depth. For example there are classes for everything under the sun, like the Entry of IPv6 addresses. Stuff i personally would have overlooked. I guess thats why i get the semi-big bucks.

Needless to say the folks at apple know how to design a framework, and have done a great job in the absence of namespaces, to provide rigid catagorization of classes.

Class names are nice and logical, for example any class ending with 'layer', is most likely a subclass of BRRenderLayer, eg. BRListLayer or BRTextMenuLayer.

The experience has also made me feel like i've been using the framework, rather than an outsider, looking in. So hopefully in the coming days i can actually leverage this thing to do something other than allow me navigate tv series from the comfort of my bed.

Quote of the Day
"It's a pitty they made so much fuss about gay cowboys, it's actually a decent film"

I happen to think brokeback mountain is a half decent flick

Sunday, May 18, 2008

Snake in the torrents ...

I decided to branch out last week and use python seriously for the first time.

Turns out it is as good as all the praise it gets. This conversion was round about the same time i switched to Transmission for my torrenting needs as the jre + azuerus don't do my memory usage any real favours. The main thing that i love about azuerus was the fact that i could have it subscribe to a rss feed and download "linux iso's" automatically. Coupled with the fact that everyones favourite release group, EZTV provides there releases in the RSS form, it was perfect. However the plugin stopped working correctly about a month ago and i've been forced to actually operate my torrent client, gasp!

Anyways, while having a shower (Yes, i come up with concepts in the shower), i thought maybe i can replicate that functionality using python! Transmission has a feature that makes it scan a folder for torrents, so in theory i would simply need to do the following ...
  • Read a list of files/shows
  • extract the respective links from a rss/xml feed
  • calculate which ones are the most recent
  • download the torrent files
Below is the entire script. It stores all torrent information in sqlite database, meaning that you can extend anyway you want. The script is released under GPL 2.0. I haven't done any real testing, but it works fine with the following conditions
  • Python 2.5.1
  • OS X 10.5
  • Atom RSS source feed (Mininova)
My plan to schedule it as a cron job and sit back and watch.

Python



#Channel 0.1
# Jonathan Dalrymple
# May 17th, 2008

from xml.etree import ElementTree as ET
import os
import shutil
import sqlite3
import urllib

currentDirectory = os.path.dirname( os.path.abspath( __file__ ))

#Create SQL
dbConn = sqlite3.connect( os.path.join( currentDirectory,"torrentsDB") )

#Create the new table
sql = "DROP TABLE IF EXISTS torrents"

dbConn.execute( sql )

sql = """
CREATE TABLE IF NOT EXISTS torrents (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
date TEXT,
url TEXT
)
"""

dbConn.execute( sql )
dbConn.commit()

#Get XML file
response = urllib.urlretrieve( "http://www.mininova.org/rss.xml?user=eztv" )

shutil.copyfile(response[0], os.path.join( currentDirectory,"rssSource.xml") )

xmlFile = os.path.join( currentDirectory, "rssSource.xml" )

try:

tree = ET.parse( xmlFile )

selection = tree.getiterator('item')

i = 0
#For each item tag
for element in selection:
#Get the request elements from the selection

title = element.findtext('title')
date = element.findtext('pubDate')
enclosure = element.find('enclosure').attrib['url']

sql = "INSERT INTO torrents (title, date, url ) VALUES ( '%s','%s','%s')" % (title, date, enclosure)

dbConn.execute( sql )

i += 1

#Commit records
dbConn.commit()

print '%d Torrents have been processed and added to the database' % (i)

except Exception, inst:
print 'Parse Error: %s' % (inst)

#Read the config file for the shows
configFile = file("shows.txt")
shows = configFile.readlines()

#Get the url for the show
print "The following torrents where found ..."

for show in shows:

dataSet = dbConn.cursor()

dataSet.execute( "SELECT title, url FROM torrents WHERE title LIKE '%" + show.rstrip() +"%' ORDER BY id DESC LIMIT 1" )

row = dataSet.fetchone()

#Test to ensure that a record exists
if type(row) == type(tuple()):
try:
print row[0]

#download the torrent file
response = urllib.urlretrieve( row[1] )

newFilename = os.path.join (currentDirectory, show + ".torrent")
#Move from the temp folder
shutil.copyfile( response[0], newFilename )

except Exception, inst:
print 'Download Error: %s' % (inst)

print 'Complete'


Lastly to create the config file, just open your favourite text editor and list your tv shows, delimited using return, mine looks like this

Lost
Battlestar Galactica
House
Cops
American Dad

It's not case sensitive, so don't panic.

Tuesday, April 08, 2008

touch base

I've been reading Microsoft's Code Complete in recent weeks. I highly recommend it for those of you, who like myself are mostly self taught. Yes we may be trying to b rockstar programmers but, we can't plan or organize a project to save our lives.

With that being said i've got a couple of old projects and a few new ones in the pipeline. As usual most are open source. As the term winds down and the amount of time i have to spend grows larger i hope to release a few.

Also as usual for the summer, i'm looking for work for the summer so if you run a start up and your looking for a half decent programmer in and around greater london and the south west, drop me a line.

Thursday, February 21, 2008

Coming to Alderaan



My favourite Youtube video of the year, enjoy

Introducing JGrid 0.01: Simple inline Table Editing

Introducing Jgrid.

Basically i got fed up of the sheer amount of configuring that was required by most inline data grid editing systems. And because programmers are lazy, and big headed, i wrote my own.

Currently it's very rough around the edges, and i would imagine it's got a few bugs. Not to mention all the console/debuging code still in place. But i am releasing more for feedback purposes.

I'm always looking to improve my development practices, so please tell me what you think.

Jgrid was built on top of jquery, and is a jquery plugin. I've built it using jquery 1.2.3, which is included in the release package below. A Documentation document (PDF/ODF) is also included as well as a basic html page, which draws data from a database, [HINT: it will break when you run it on your machine!], i plan to update in version 0.02 when i have more than a single callback.

Enjoy.



Download

Wednesday, January 30, 2008

Memories ... of Lego Aircraft Carriers

Over at Gizmondo, they are showing some of the best lego sets in history.

I'm quite proud to say, that they in fact have two of my favorites.




I spent may a good day, in PJ's playing with them in my grandma spare room in jamaica. She had a kingsize bed, which i used as underground airport, and the wardrobe that was the super secret submarine base. Not to mention the drawers with where the hills surrounding the valley, which had my custom built lego aircraft carrier, which could store a helicopter, a VSTOL aircraft, and a hovercraft, all technic size i might add! It also had two escape canoes, as well as an armory, and control tower, SAM launcher and ....

Ok, i remember it a little too vividly considering it's been 6 years since i last saw it, and a few more since i last really played with it. But it was a lot of fun, and my favorite toy of my childhood. Oh, and to add it could also carry my weight on the carriers deck, thanks to a well placed supporting beam that ran across the ship and tied the hull walls together! It was 2 feet long, and foot wide, and half a foot high.

Enough carrier talk for one night don't you think!

Quote of the Day
"I Guess to you Starbucks is like Dr. Phil"

Some people seek solace at Starbucks

Sunday, January 27, 2008

The gift that just keeps on giving

After my 14 hour stint yesterday, i'm back on the trail.

Today i've cooked up a Javascript shopping cart. In true fashion it's all OO, and shiny. However very unlike me, it's JS library agnostic! Yes, thats right, i wrote by very own 'getElementById' staements!. I've only provided methods for adding, removing, and getting the price of all the objects. There is also a method for updating a ordered or unordered list, with the items stored in the object.

Javascript (No Library required!)

//Basket Object
//Library agnostic
var BasketObj = function(){
this.items = new Array();
this.bindToElementId = null

//Add an object to the basket
this.addItem = function( pObj ){
retVal = false;
if( pObj.name.length > 1 ){
this.items.push( pObj );
console.log('Object added to basket');
retVal = true;
}
else{
console.log('Not a valid object');
}

return retVal;
}
//Remove the first matching item from the basket and return it
this.removeItem = function( pItemName ){
var retVal = null;

for(i=0; i < this.items.length; i++){

if( this.items[i].name == pItemName ){

console.log('Object removed from basket')
// reference the obj
retVal = this.items[i];
//dereference it
this.items[i] = null;
//exit the loop
break;
}

}

return retVal;
}

//Calculate the total basket value
this.total = function(){
var retVal = 0.00;

for(i=0; i < this.items.length; i++){
retVal += this.items[i].price;
}

return retVal;
}

//Updates the gui display of the object
this.updateDisplay = function(){
if( this.bindToElementId != null ){
//Empty the element first
document.getElementById( this.bindToElementId ).innerHTML = '';

//Sort the array before we print
//this.items.sort();

//Now proceed to fill it
for(i=0; i < this.items.length; i++){
document.getElementById( this.bindToElementId ).innerHTML += '<li>' + this.items[i].name + '</li>';
}
}
}
}


To use it, you must first create the object,


x = new BasketObj();


Once thats done you can set it up, the only thing that you really need to set, is the id name of the object you wish to have the results shown in. This is store in a variable called bindToElementId.

x.bindToElementId = 'basketList';


Now you can add your objects to it. Your objects can be as complex as you want, however they must have the following properties,
name: This is the display name for the object, and the name that will be used for internal lookups
price: This is the value that will be added to create your total,

You use the addItem() to add items to the object, and the removeItem( nameOfObject ) to remove items.

To update your list with the current objects you call updateDisplay. And to get the total value of all the objects you can call total().

One other thing to mention, is that i use console.log statements, so be aware of those, and also i check for the name attribute before adding objects to the internal array, so don't try and add them, and prototype the method to your object later on.

Anyways, this object features in my DFTI coursework, which i've been streaming though over this past weekend, i've now implemented the Drag and drop shopping and it looks a little something like this...



I still have to do the admin page, and stock control logic, however imagine this could be done in a day or so.

When it rains it php's

Ever wanted to convert a camel case string into something more user friendly?

Introducing the super dupa know it all function, should be good for PHP 4+

PHP

/*
Make a camel case string user friendly ^_^
*/
function implodeCamelCase( $pStr, $delimiter = ' '){

$strArr = str_split($pStr);
$retArr = array();

foreach( $strArr as $val ){

if( ord($val) <= 90 ){
array_push($retArr, ' ');
}

//add to return array
array_push($retArr, $val);
}

//explictly destroy array
$strArr = null;

return mb_convert_case(implode('',$retArr),MB_CASE_TITLE);
}


It's a bit rough around the edges, anything thats not a lower case character or anything else with a decimal ascii number over 90, will have a space inserted before it, of course thats easy enough to tweak.

Saturday, January 26, 2008

Json Encoding

For a enterprising young developer like myself, i don't take advantage of json enough. So since i'm in the mix at the moment, with my DFTI course work, i thought now would be a good time.

Unfortunately the json_encode() function that i had seen in the PHP documentation, is only in the CVS distributions at the moment (v 5.1.2), so i came up with the below.

PHP

/*
This function converts an array to a Json string.
*/
function jsonEncode( $pArr ){
$arr = Array('{');

foreach( $pArr as $val ){

if( is_numeric( $val) ){
array_push($arr, $val );
}else{
array_push($arr, '"');
array_push($arr, $val);
array_push($arr, '"');
}
array_push($arr,',');
}
//Remove trailing comma
array_pop($arr);

return implode('',$arr);
}

/*
This function converts an associative array to a Json string.
*/
function jsonEncodeAssoc( $pArr ){
$arr = Array('{');

foreach( $pArr as $key => $val){
array_push($arr, '"');
array_push($arr, $key);
array_push($arr, '"');
array_push($arr, ':');

if( is_numeric( $val ) ){
array_push($arr, $val);
}
else{
array_push($arr, '"');
array_push($arr, $val);
array_push($arr, '"');
}

array_push($arr, ',');
}

//Remove trailing comma
array_pop($arr);

array_push($arr,'}');

return implode('',$arr);
}


Both functions take either a regular array, or a Associative and converts it to a json string, which looks like ...


{"id":1,"name":"Ham And Pineapple","description":"<p>Fusce magna sem, gravida in, feugiat ac, molestie eget, wisi.</p>","categoryId":1,"hasNuts":0,"vegetarians":0,"imagePath":"ham-and-pineapple.gif","price":4.95}



The above is just some data from my database. It's a pizza ordering system. I plan to go all ajaxan with a Drag and drop shopping cart, as well as some other shiny stuff.

I haven't a clue what i'm going to do concerning javascript, i'm looking at mootools, mochikit, and of course jquery and maybe even yahoo ui. Might be a last minute thing.

Sunday, January 13, 2008

My Broadband got upgraded!

Or at least so it would appear

Happy posting :), and don't write anything too stupid!

I don't know about you, but this is the fastest torrent speed i've witnessed, ever. Speedtest.net put the connection speed at 6mb!

Wednesday, January 09, 2008

Happy New year, have a server for 08

Happy 2008.

I'm in the middle of finishing up my Object Orientated Application Assignment, and i ran across this piece of code in my repository.


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

public class ServerInstance {

private Socket Connection;
private BufferedOutputStream Outbound;
private InputStream Inbound;
private HTTPData RawHttpData;

private int listeningPort;

//ClassFlags
private boolean connectionEstablished = false;
private boolean instanceComplete = false;

public ServerInstance(){
//This one Sets all variables to defaults
listeningPort = Preferences.DEFAULTPORT;
}

/*public ServerInstance(Preferences){

}*/

public boolean run(){
ServerSocket ListenSocket;

boolean retBool = false;
boolean endLoop = false;
int readValue = -1024; // Set to extreme value to show that it is default;
int i = 0;

/*
* How the Server Will work
*
* 1. Get the Data from the browser / Read the Stream
* 2. Send Data off to extract the headers
* 3. While Data is being Processed Send data back to the client
* 4. Flag that server action is complete, and shutdown and clean up
*
*/
try{
ListeningSocket = new ServerSocket( listeningPort );

Connection = ListeningSocket.accept();

connectionEstablished = true;

//1. Get Data from Browser
Inbound = Connection.getInputStream();

Outbound = new BufferedOutputStream ( Connection.getOutputStream() ); //Place output in a Buffered Stream

//Write to both Objects simultainously
while( !endLoop ){
readValue = Inbound.read();

if(readValue != -1){
Outbound.write( readValue ); //Send data to the client
RawHttpData.write( readValue ); //Write data to a HTTPData Object
}
else{
endLoop = true;
}
i++;
}

Outbound.flush(); //Make sure all the data has been sent back to the browser
//Just while we code
System.out.println("Server: has RX/TX " + i + " Bytes of data");

//4. Clean up
Inbound.close();
Outbound.close();
Connection.close();

instanceComplete = true;
}
catch(IOException e){
System.out.println("<-- Server Error -->");
System.err.print( e );
}
catch(IllegalBlockingModeException e){
//I doubt this will come up, but refer to java documentation on serversocket.accept() in the event it does
System.out.println("<-- Server says no! -->");
System.err.print( e );
}
finally{
return retBool;
}
}

public boolean isConnected(){
return connectionEstablished;
}

public boolean isComplete(){
return instanceComplete;
}
}


Code is released under the GPL 2.0 License, go forth and improve (and credit).


This is a working server implementation in java, a relic from my isolation project,( Isolation was meant to act as a personal proxy, similar to how google gears works, however their wouldn't need to modification to the web app, as isolation was meant to pre-fetch the data, based on monitor the users actions/http requests.).

Anyway as you can imagine this was a big project, coupled with my second major data disaster, it didn't really ever see the light of day.

Couple of things to mention, the Preferences class was a data structure to store, ... well user preferences, and the class was meant to implement the runnable interface, so that you could operate multiple server instances.

I learnt a lot researching for it, and thanks to it i have a very good idea of how the HTTP protocol works, however i think it was a little too complex for someone at my current level, i should really stick to trying to reverse engineer front row, and learning lisp.

On the note of the reversing of front row, a plugin called sapphire was released last year. From what i can determine they have worked out how to beat apples protection scheme governing the loading of foreign NSbundles (Yeah, i know about them!). So when i finally get around to it, i'll (try to) reverse it as well.

Quote of the Day
"Rave for business"

I love Capitalism, don't you

Saturday, December 29, 2007

rounded corners anyone?

You may notice my new rounded corners.

Well in true fashion, they're CSS corners.

Instead of loading up one of the many css corner library, i decided to take the opportunity to write my own. The other plus is that as this is a blogger account, i have no real file storage, so linking against the jquery lib makes way more sense.


//Corner rounding function
roundCorners = function( pElement, pSize, pForeground, pBackground ){
//Logging
/*
console.log( 'Corner size ' + pSize);
console.log( 'Fore color ' + pForeground );
console.log( 'Back color ' + pBackground );
*/
if( pBackground.match('none') != null ){
pBackground = 'transparent';
//console.log('transparent background');
}

//constants
containerStr = '<div class="cornerContainer" style="margin:0px 0px;height:auto;background:'+ pBackground +'"></div>';
cornerAttributesStr = 'border:none;overflow:hidden;height:1px;background-color:'+ pForeground +';';


//Reset the parent element
$( pElement).parent().css('padding','none');

//Insert container Div and set background color
$(pElement).prepend( containerStr );
$(pElement).append( containerStr );

for(i=1;i < pSize; i++){
$('div.cornerContainer').eq(0).append('<div style="' + cornerAttributesStr + 'margin: 0 '+ Math.round(pSize/i) +'pt"></div>');
//console.log('Insert element ' + pSize/i);
}

for(i=pSize; i > 1; i--){
$('div.cornerContainer').eq(1).append('<div style="' + cornerAttributesStr + 'margin: 0 '+ Math.round(pSize/i) +'pt"></div>');
}

}


Currently it doesn't support chaining, however according to my understanding, you just have to encapsulated within a jquery.extend, and change the passed object references call and your good to go.

Tuesday, December 25, 2007

New Design

Just a quick note to say here is the new design. Nice and light weight, no shiny stuff (yet). I'll add in some javascript nuts and bolts later, but now i have to set the table for christmas dinner. Btw, this took me like 3 hours, not too bad considering i have to cut and paste into the online editor.

Merry Christmas

Saturday, December 22, 2007

And to think people think i waste my time

I've been hitting the Dev Trail pretty hard over the last week or so. My fringe Cocoa/Objective-C skills are getting better each day. To give you an idea of what my Programming space looks like here's a screenshot.
The Work zone
To summerize, i'm in the middle of linking the mysql-cocoa framework into my project. Now i have hit a slight snag on that front. The snag being that it looks like i can't sell the app.

Why? Because the use of the GPL'd open source framework means that i have to release the source code. Now for a long time, i have considered releasing an application that one has to pay for, but is also open source. However with this kinda of app, my target market, most likely already has xcode installed, and would find it trivial to download the source and hit 'build'.

I'm gonna email the FSF, and find out what they have to say. But i think i might try and release this as an open source application. I love open source as much as the next guy, so maybe this is the way it should go down.

In other news i've finally popped for a Western digital 250GB notebook hard drive. After some stupidity (and a trip to Eastleigh) on my part it's churning away inside my Macbook. The old drive is now a Time machine Drive, speaking of time machine ...

Interface design at it's wildest

It's a nutty excuse for an interface, but it really is fantastic. Pre-Time Machine, i used a backup script i 'wrote' in automator, however it wasn't as flash as this. However it did zip my documents folder from almost 2GB to 700MB which always impressed me, or at least one side of me.

Well it's almost the end of another year and this blog has seen quite a few annual transitions now, 4 to be correct. In keeping with RSS tradition i'll have the usual wrap up posts, plus a 4/5 redesign. Hopefully this time done properly with more ajax than you can shake a stick at, and a cleaner ui, after all i'm a professional now ........



Quote of the Day

Caption

Sunday, December 16, 2007

One byte

Not sure what all the moaning was about, but i must say i like the look of the new iplayer from the bbc. It's not a big slab of flash. Nice ajax like effects. Works in safari. A nice job i would say overall.

I doubt it works for those outside these fair shores, but if it does work i would recommend.

Btw this is post 255, hence the title.

Merry Christmas

Wednesday, December 12, 2007

Reg Exp

In case you ever need them, here are a couple of regular expressions for dealing with dates.

For dates like this: December 19, 2008

[A-z]{3,8}.[0-9]{1,2}.{1,2}[0-9]{4}


For dates like this: 05/03/87

[0-9]{1,2}/[0-9]{1,2}/[0-9]{1,2}


They form part of my fantastic plan to .... write loads of regular expressions ^_^

Tuesday, November 13, 2007

Google's Android: My two cents

I love it. At least from a developers point of view. Now the real question is, can they get the devices with the right form factors to really complete with the big boys, MS, Symbian, and now Apple.

With HTC behind them, there is no reason why they can't. So why does a tech skeptic like me like this FOB (Fresh off the boat) platform so much. Well here's why

  • SDK for OS X, Linux & Windows (Take note Apple!)
  • It uses Java as the language of choice.
  • Each app runs in VM, they borrowed an idea from palm os(kinda)
  • They provided a C Api
  • XML GUI layouts, nice and open
  • The Platform is wide open
If you wanna look at this from a web 2.0 mashup point of view, its like the following

Microsoft's level developer support + Googles Open-ness + Apples inovation

Alternatively Lets compare it to it's rivals

Symbian - 'Modern' widely supported Language (Java vs C++).
Microsoft - It doesn't look like it was retrofitted to be used in a phone
Palm - Multiple device makers, means better form factors + it's a brand new os
Apple - It's not a Objective-C only world, and locked down like a [insert word of choice]
Others - It's got traction, and the developer community behind it, we all love google.

I'm getting to work on developing some apps for this platform. As i said it's got my support, it's solid under the hood, and i look forward to queuing for my first device. 

BTW i hate the iphone if anyone is wondering.


Quote of the Day
Red Light District

Some are more hungry than others...

Tuesday, November 06, 2007

Quick and Dirty Leopard Dock Image replacement script

This one is for all the dock hackers out there. I'm gonna try and roll this into a application during my lectures today ^_^

Cut and paste the script into a text editor of your choice, and save it as "dockSwitcher.sh"

To use this save your new dock images on the desktop and then run the script. Beware i haven't tested as i A. Use the non-glass dock, and B. didn't have time. So use with caution.


#!/bin/bash
## Quick and dirty Dock Image Replacement script
## Jonathan Dalrymple
## November 6, 2007

##Root Checking
## Thanks to
## http://blog.mecworks.com/articles/2006/02/23/bash-scripting-tip-running-a-script-as-root/
CMDLN_ARGS="$@" # Command line arguments for this script
export CMDLN_ARGS

# Run this script as root if not already.
chk_root () {

if [ ! $( id -u ) -eq 0 ]; then
echo "Please enter root's password."
exec su -c "${0} ${CMDLN_ARGS}" # Call this prog as root
exit ${?} # sice we're 'execing' above, we wont reach this exit
# unless something goes wrong.
fi

}

# Check if user is root
chk_root

##Back up dock
cp /System/Library/CoreServices/Dock.app ~/Dock.backup.app

##Remove the old files
rm /System/Library/CoreServices/Dock.app/Contents/Resources/scurve-l.png

rm /System/Library/CoreServices/Dock.app/Contents/Resources/scurve-m.png

rm /System/Library/CoreServices/Dock.app/Contents/Resources/scurve-sm.png

rm /System/Library/CoreServices/Dock.app/Contents/Resources/scurve-xl.png

##Put in the new files
mv ~/Desktop/scurve-l.png /System/Library/CoreServices/Dock.app/Contents/Resources/

mv ~/Desktop/scurve-m.png /System/Library/CoreServices/Dock.app/Contents/Resources/

mv ~/Desktop/scurve-sm.png /System/Library/CoreServices/Dock.app/Contents/Resources/

mv ~/Desktop/scurve-xl.png /System/Library/CoreServices/Dock.app/Contents/Resources/

##Remove dock images from desktop
rm ~/Desktop/scurve-l.png

rm ~/Desktop/scurve-m.png

rm ~/Desktop/scurve-sm.png

rm ~/Desktop/scurve-xl.png

##
killall Dock


Monday, November 05, 2007

Leopard Hacking : Front Row

Thanks to my coffee, i can't seem to sleep. So to pass the time i decided to do some more work on a new brain wave i just had this evening.

It centers around front row. Well actually it had nothing to do with front row, however building on top of front row makes more sense, than starting out from scratch.

Now as you may or may not know, like most of the cool gui stuff on osx front row is a closed environment. Which means it's hacking time. Something i always wanted to play with is a decompiler. Now i'm no Dmitry Grinberg, so assembly doesn't wash with me. Instead i found this little gem.

After a a brief compile it gave me this wonderful output



struct _NSZone;

/*
* File: Movies
* Arch: Intel 80x86 (i386)
*/

@protocol BRMenuListItemProvider
- (long)itemCount;
- (float)heightForRow:(long)fp8;
- (BOOL)rowSelectable:(long)fp8;
- (id)titleForRow:(long)fp8;
- (id)itemForRow:(long)fp8;
@end

@protocol NSObject
- (BOOL)isEqual:(id)fp8;
- (unsigned int)hash;
- (Class)superclass;
- (Class)class;
- (id)self;
- (struct _NSZone *)zone;
- (id)performSelector:(SEL)fp8;
- (id)performSelector:(SEL)fp8 withObject:(id)fp12;
- (id)performSelector:(SEL)fp8 withObject:(id)fp12 withObject:(id)fp16;
- (BOOL)isProxy;
- (BOOL)isKindOfClass:(Class)fp8;
- (BOOL)isMemberOfClass:(Class)fp8;
- (BOOL)conformsToProtocol:(id)fp8;
- (BOOL)respondsToSelector:(SEL)fp8;
- (id)retain;
- (oneway void)release;
- (id)autorelease;
- (unsigned int)retainCount;
- (id)description;
@end

@interface RUIMoviesAppliance : BRAppliance
{
}

+ (id)moduleKey;
- (id)init;
- (void)dealloc;
- (id)moduleIconName;
- (float)moduleIconReflectionOffset;
- (id)moduleName;
- (id)moduleKey;
- (id)applianceController;

@end

@interface RUIMoviesApplianceController : BRMediaMenuController
{
NSArray *_headerRows;
NSMutableArray *_titlesWithUnplayedContent;
RUIMovieFolderCollection *_movieFolderCollection;
BRMovieTrailersProvider *_trailersProvider;
unsigned int _hasLocalMovies:1;
unsigned int _movieTrailersPreviewRequested:1;
unsigned int _movieTrailersSelected:1;
BRDataStore *_dataStore;
Class _msClass;
}

- (id)init;
- (void)dealloc;
- (id)musicStoreBaseType;
- (BOOL)menuDisplaysLeftIcon;
- (void)networkStatusChanged:(id)fp8;
- (BOOL)isVolatile;
- (id)loadModelData;
- (void)refreshControllerForModelUpdate;
- (BOOL)shouldRefreshForUpdateToObject:(id)fp8;
- (long)defaultIndex;
- (void)itemSelected:(long)fp8;
- (void)wasExhumedByPoppingController:(id)fp8;
- (void)wasPushed;
- (void)willBePopped;
- (void)wasPopped;
- (id)previewControlForItem:(long)fp8;
- (BOOL)brEventAction:(id)fp8;

@end

@interface RUIMoviesApplianceController (AsyncNotifications)
- (void)_movieTrailersLoaded:(id)fp8;
- (void)_swapNewController:(id)fp8;
@end

@interface RUIMoviesApplianceController (DataSourceAccess)
- (id)_movieTrailers:(id *)fp8;
@end

@interface RUIMoviesApplianceController (MediaParadeBuilders)
- (id)_moviesFolderParade;
- (id)_movieTrailersParade;
- (id)_stingrayMediaPreview;
@end

@interface RUIMoviesApplianceController (MovieLoading)
- (void)_cacheUnplayedTitles;
- (BOOL)_hasUnplayedMovies;
@end

@interface RUIMoviesApplianceController (MovieSelection)
- (id)_movieSelectedAtIndex:(long)fp8;
@end

@interface RUIMoviesApplianceController (MenuBuilding)
- (id)_buildMovieTrailersMenu;
- (id)_movieTrailersController:(id)fp8;
- (id)_buildMyMoviesMenu;
- (id)_stingrayFrontPageController;
- (id)_headerRows;
@end

@interface RUIMoviesApplianceController (DataProviders)
- (id)itemForRow:(long)fp8;
- (long)itemCount;
- (id)titleForRow:(long)fp8;
- (float)heightForRow:(long)fp8;
- (BOOL)rowSelectable:(long)fp8;
@end

@interface RUISDMovieTrailersController : RUIMovieTrailersController
{
}

- (id)initWithTrailers:(id)fp8;
- (id)previewControlForItem:(long)fp8;
- (id)titleForRow:(long)fp8;
- (long)defaultIndex;
- (id)itemForRow:(long)fp8;
- (long)itemCount;
- (void)itemSelected:(long)fp8;

@end

@interface RUIMovieTrailersController : BRMediaMenuController
{
NSArray *_trailers;
}

- (id)initWithTrailers:(id)fp8;
- (void)dealloc;
- (BOOL)isNetworkDependent;
- (void)itemSelected:(long)fp8;
- (long)itemCount;
- (id)itemForRow:(long)fp8;
- (id)titleForRow:(long)fp8;
- (float)heightForRow:(long)fp8;
- (BOOL)rowSelectable:(long)fp8;
- (id)previewControlForItem:(long)fp8;

@end

@interface RUISDMovieTrailersController (Private)
- (id)_HDMovieTrailers:(id *)fp8;
@end

@interface RUIMovieTrailersController (Private)
- (id)_movieTrailersTitle;
@end

@interface RUIMovieDirectoryController : BRMediaMenuController
{
RUIMovieFolderCollection *_collection;
NSString *_path;
}

- (id)initWithMovieFolderCollection:(id)fp8;
- (void)dealloc;
- (id)moviesForParade;
- (void)itemSelected:(long)fp8;
- (id)previewControlForItem:(long)fp8;
- (id)mediaPreviewMissingMediaType;
- (BOOL)mediaPreviewShouldShowMetadata;
- (BOOL)mediaPreviewShouldShowMetadataImmediately;
- (long)itemCount;
- (id)itemForRow:(long)fp8;
- (id)titleForRow:(long)fp8;
- (float)heightForRow:(long)fp8;
- (BOOL)rowSelectable:(long)fp8;

@end

@interface RUIMovieFolderAsset : BRBaseMediaAsset
{
NSString *_displayName;
NSURL *_mediaURL;
NSString *_folderPath;
BRImage *_posterImage;
BOOL _requestedImage;
}

+ (id)assetForName:(id)fp8 folderPath:(id)fp12 andMediaURL:(id)fp16;
- (void)dealloc;
- (void)setDisplayName:(id)fp8;
- (void)setMediaURL:(id)fp8;
- (void)setMovieFolderPath:(id)fp8;
- (id)assetID;
- (id)title;
- (id)mediaURL;
- (BOOL)hasCoverArt;
- (id)coverArt;
- (id)dateAcquired;
- (id)mediaType;

@end

@interface RUIMovieFolderAsset (ArtLoading)
- (void)_loadImage:(id)fp8;
- (void)_imageLoaded:(id)fp8;
@end

@interface RUIMovieFolderCollection : BRBaseMediaCollection
{
RUIMovieFolderCollection *_parent;
NSString *_displayName;
NSString *_folderPath;
NSArray *_childCollections;
NSArray *_childAssets;
}

+ (id)collectionForName:(id)fp8 folderPath:(id)fp12 andParent:(id)fp16;
- (void)dealloc;
- (void)setParent:(id)fp8;
- (void)setDisplayName:(id)fp8;
- (void)setMovieFolderPath:(id)fp8;
- (id)childCollections;
- (id)parentCollection;
- (id)collectionType;
- (id)collectionID;
- (int)count;
- (id)mediaAssets;
- (id)title;
- (id)titleForSorting;
- (BOOL)hasCoverArt;
- (id)coverArt;
- (BOOL)isLocal;

@end

@interface RUIMovieFolderCollection (Private)
- (void)_generateCollectionChildren;
@end

@interface BRMediaCollectionType (FolderCollectionExtension)
+ (id)folderCollection;
@end

What you see here is the headers/interface & protocol files for all the different classes located within Front rows movies appliance.

If you want to see your own front row app, it's located @ /system/library/coreservices/front row.app

Now i had heard that some good folks over at Awkward TV forums have hacked appliances for the Apple TV which is basically what the new front row on leopard is, however these don't seem to work 'out of the box', and apparently Apple updated this version before the roll out.

Coupled with all the above, i have reason to believe that the new appliances are digitally signed by [chinese] ni cai, Apple.

By reasoning for this, is a did a hex dump (using 0xED) of the appliance executables, and found the following string(s) @ 135535

"Apple Certification Authority1301U*Apple Code Signing Certification Authority"

Now just after typing the above sentence, it dawned on me that this might be for the transactions with the ITMS, for movie trailers, however i checked the settings appliance and found the same thing.

Also i tried deleting the various applications from a running front row, and it handles them gracefully, and also doesn't mind having new ones dropped in. I tried droping in the rss apple tv plugin, however it didn't like it very much.

I'm a programmer, not a hacker so this is about the limit of my skill, especially if it envolves digitally signed apps. I can barely deal with the symbian signed apps, never mind about these ones. If got some ideas or feel like getting dirty and dodging some DMCA takedown notices let me know.

UPDATE

i found this URL above the previous string, http://www.apple.com/appleca/

turns out that the certificate may be freely available, which might make life a tad bit easier.

PS. to any one wanting to warn me for breaking the law, i'm not a US resident ^_^

Wednesday, October 31, 2007

Mobile Web development

In recent months I've seriously considered getting into mobile application development. My platform of choice has been symbian thus far. However yesterday something dawned on me. Most people don't understand that modern phones are miniature computers hiding in pink cases. As such the idea of additional applications is moot. However what everyone is now seeing is that the internet on mobile devices is possible. In this crazy online world of ours that means one thing web 2.0!

So from today, i'm gonna put some fuel into creating mobile web 2.0 applications. I have a vague idea of where i'm going, but only time will tell.

In other news, this is my 250th post, meh.

I'm slowly becoming myself again, best reflected by the fact that i have time to write this monologue!

Plus i got the 24" in the end, Benq fp241. ....

Well until another time




Quote of the Day

Caption

Tuesday, August 07, 2007

Database Table Size Calculations

As a professional Developer, every once in a while you'll need to create a Database, for one reason or another. It's always nice to apply structured thought to your design process and work out your proposed database size before who release it upon the unsuspecting database server.

It's kinda obvious to do, but just in case heres how i do it.

First create your data dictionary. In my case it was for a questionnaire management system, (QMS, might release it as OSS when i'm done).

i wanted to dynamically generate a new table for each questionnaire, so i need to work out the system limits before hand.

first we would have our "user id's"

id - UInt
hostName - 128 byte (unicode 64 character string)
ip addr = 15 bytes (it's ip v6)
assocQuestionnaire = 4 bytes aka 32bit unsigned integer

then depending on the questionnaire you could have upto 32 questions/ comment, (32 columns). These could then store upto 1024 characters so thats basically double in UTF-8, so 2048 bytes, bringing in each row at almost 65Kb, now the company i work for has 40 000 members of staff, so lets assume they all anwser the same questionnaire (Great advertising for me), the database would swell to 2.5 Gb!

Well i think thats sight over kill, so by tweaking the the system to only implement the larger fields when requested by a user, and assuming that they only want one comment field per questionnaire, we get a much more wholesome figure of 100 Mb.

So to summerize the formula is

sum( column types ) * num of rows.

Remember this is only an estimate, and doesn't account for the master tables or relationships or any of that other RDMS goodness. So it's a guide not, E=MC2

Jonathan

Saturday, August 04, 2007

Display Madness

For once i have a little time, which makes a huge change. In the last hour or so i've been exploring my options around getting a new display to help support my Mac lovin life style. However what should be a joy filled ride through the online e-commerce world, is turning out to be a little less simple then i had imagined.

I have a budget of around £600.
My current setup is two 19" @ 2560 * 1024

However there is a major problem with my current setup, My Blackbook only supports one display. However with a little box from matrox it can support two, but at a maximum resolution of 1024 * 768 each or 2048 * 768.

Current i share the setup with my nix box, but that is getting axed (Yes blu-ray is dead/dying) in favor of consolidating all my development onto one physical machine, and running nix, solaris, windows via parallels.

Now normally i would the following choices given the price.

2 x 22" displays (3360 * 1050)
1 x 24" display ( 1920 * 1200)
1 x 27"
1 x 26"
Now two 22's would be nice, not only cause because it's big but it's also a Jay-z song(well in reverse)!

Now based on current machine specs i've actually got three choices
1 x 24" display ( 1920 * 1200)
1 x 27"
1 x 26"

These are all below my current resolution, so maybe it's the machine that needs changing ...

Ok, lets do the math

Macbook pro (legit) £1149 with student discount
2 22" displays £ 500
matrox dual head to go £140

total £1700!

sweet price point, not. What makes it worse, is that i love the macbook's form factor and would hate anything bigger. ie MB pro.

Plus for that price i could get a mac pro which i have often considered and drooled over with phil. (the computer not phil).

The other solution is to build a osx86 machine, however as developer, and with Leopard coming doing all my work on a unsupported, illegal, in-frequently updated, hacked platform strikes me as dumb.

So that leaves the single units

All of which mean i lose about 1/2 million pixels, and a couple of inches.

Heres the price breakdown
24" £430
26" £ 500
27" £ 680

So on price the 24" is a winner models in that range, that have 8bit color panels, good response times, and adjustable stands, and multiple inputs are ...
Dell's 2407wfp
Benq's 241 wp ( HDMI included!)

On the 26"'s there is one that i know of
Acer 2604
It's got a crapy stand, and no Digital inputs, infact it's only got a VGA input

And then there is 27's

Dell 2707wfp

Which is basically the 24" dell with a phat-er panel and no rotation. And a pixel pitch closer to a 19" lcd (0.294 vs 0.3)

Now we consider the pros and cons of the 24 vs 27

1. I have personal issues with spending seven bills on a lcd display, that i don't really need while people starve to death, and go to war over food.
2. The pixel pitch of the 27 is ideal, the high pixel pitch of my 19's is why i sprang for them over the 17"'s.
3. No rotation, how do i show off those cool XGL effects without being able to rotate the display as well!
4. Both give me less working resolution then i have currently.

Conclusion...

I'll wait to see if apple brings out a super notebook next week, that razor thin macbook pro that all mac geeks dream about, and if it's what i want i'll upgrade.

BTW

i recently bought my name (www.jonathandalrymple.com) as well as a couple of domain names for some projects that are in the pipeline.

Thursday, July 19, 2007

CSS research

I'm completely knackered, but research is my life. One of my many clients wanted a semi transparent div. Now i say div, but they just want it to look shiny.

Basically then want an element with appox 20% opacity. Easy right, use a PNG. But that cancels out all ie versions apart from 7. How about a gif instead, you dont get alpha transparency! Well genius how about css, great, there are ways to do it on webkit, gecko, and ie, however they apply the same amount of transparency to their children.

the trick here is to think outside the box, literary...



Thanks to relative positioning, i made a solid div below my transparent div, and moved it over the transparent div, creating a the above effect. The cool things is that by modifing the z-index you can create a ghosting effect!

Best of all, there are no images used to create the above, (well apart form the obvious background pattern on the body), more testing is needed, but i think i might be on to something here.

The CSS
*{
text-align:center;
margin:0;
padding:0;
}
body{
background: url("pattern.gif");
}
div#wrapper{
margin:0 auto;
width:70%;
text-align:center;


padding:1em;
}
div#panel{
opacity: .50;
height:200px;
background: #ddd;
width:100%;
margin:0 auto;
}
div#wrapper p{
padding:1em;
background: #000;
color:#fff;
width:90%;
position:relative;
margin:0 auto;
top:-180px;
z-index:1;
}

The html


Transparent div

content goes here






Now if you excuse me, i'm off to bed

Introducing Absolution

Yes i'm alive, it may have been months since the grand plans of facebook widgets and such, but i'm back. Today i'm unleashing on the world something new(ish), A PHP framework. Now don't get me wrong it's no piece of cake, but it's not meant to be. Absolution place in the world is on shared hosts, and B grade websites, where speed of development is more important than MVC patterns and OO principles.

Well OO is always good but you know what i mean.

Currently it consists of 4 classes, that contain helper functions, that enable you to do things like print an un ordered list from a sql query in one line of code!, get a pre-sanitized variable from the query string with one line, even filter out bad characters with one line.

I plan to add more classes, and more functionality, as the framework grows up, however it's 0.01 alpha at the minute! Eventually i want this to grow into something like prototype for PHP, a lean, mean framework machine.

Also i think this place could do with a redesign, ajaxian styleee, now if only i had time.


Till another time

Quote of the Day
"We knew that when we gave it to him, that it was never gonna end up as just a simple webpage!"

My love of Jquery is starting to give me a reputation