Posts Tagged ‘Programming’

This is a howto that might come in handy to some people, but mostly I just want to document how I poked around some very angry django dragons and created something marvelous. There are also people on twitter who were wondering what the fuck I was doing.

So let’s start by describing the problem. We have a base user model named pUser (yes stupid naming convention) that is tied to a cookie, which holds an id. These users are then tied to a number of different API accounts. In my case it is Delicious, Twitter and Facebook. The user_id is also used to tie a bunch of meta data in different other models to them.

The problem is that we do not want to trouble users with a special login for our service. But they are using different computers and browsers, so the same physical user can have multiple user id’s.

However through their Delicious et al. credentials we can tie them back together into a single entity. But we do not want to trouble the rest of the code with this detail, it should just work seamlessly because otherwise we’d be forced to introduce checking for this stuff at about 50 different places in the project.

My approach to solving this goes as follows; at the end will be the three tests that indicate that the solution is valid. A hardcore test through the actual UI also confirmed that everything works.

Funky geek stuff follows, you have been warned

First we introduce a model that connects different user id’s to the main user (i.e. the first id said user was given)

class UserNormalisation(models.Model):
	main_id = models.IntegerField()
	sub_id = models.IntegerField()
 
	class Meta:
		unique_together = ("main_id", "sub_id")

Then we give our Delicious model a ModelManager that will perform duplicity checking and tie different users together as needed.

class DeliciousManager(models.Manager):
	def create(self, **kwargs):
		try:
			old = Delicious.objects.get(username=kwargs['username'])
			new = super(DeliciousManager, self).create(**kwargs)
			try:
				UserNormalisation(main_id = old.user.id,
						  sub_id = new.user.id).save()
			except IntegrityError:
				pass
			new.delete()
			return old
		except Delicious.DoesNotExist:
			return super(DeliciousManager, self).create(**kwargs)
 
class Delicious(models.Model):
	user = models.ForeignKey( pUser )
	username = models.CharField( max_length=255 )
	password = models.CharField( max_length=255 )
	isScrobbled = models.BooleanField( default=False )
 
	objects = DeliciousManager()

Basically when the createfunction is called it checks whether a Delicious model with the same username already exists and if it does, then a row is added to the UserNormalisation table to tie the two user id’s together.

And here’s the real magic, the changes we did to the pUser model.

class pUserManager(models.Manager):
	def get(self, **kwargs):
		user = super(pUserManager, self).get(**kwargs)
		try:
			id = UserNormalisation.objects.get(sub_id=user.id).main_id
			user = super(pUserManager, self).get(id=id)
		except UserNormalisation.DoesNotExist:
			pass
		return user
 
class pUser(models.Model):
	username = models.CharField( max_length=50 )
	password = models.CharField( max_length=255 )
	creation = models.DateTimeField( auto_now=True )
 
	objects = pUserManager()
 
	def __init__(self, *args, **kwargs):
		super(pUser, self).__init__(*args, **kwargs)
		try:
			id = UserNormalisation.objects.get(sub_id=self.id).main_id
			self.id = id
 
		except UserNormalisation.DoesNotExist:
			pass

The pUserManager should have a few more functions that do essentially the same thing for other operations (filter comes to mind). Essentially whenever a pUser is fetched from the db the manager will return the real user as per the UserNormalisation model.

Another trick that makes this work seamlessly even when used as a connecting model (primary key for instance) in a different table is that __init__ function. What I’ve discovered is that there it’s enough to just change the user’s id in place and everything will work.

Here are the tests that confirm all of this funky stuff actually performs as expected

	def test_normalisation(self):
		user = pUser(username="test", password="test")
		user.save()
 
		user2 = pUser(username="test2", password="test")
		user2.save()
 
		norm = UserNormalisation(main_id=user.id, sub_id=user2.id)
		norm.save()
 
		fixture = pUser.objects.get(id=user2.id)
		self.assertEquals( fixture.id, user.id )
 
	def test_normalisation2(self):
		user = pUser()
		user.save()
		user2 = pUser()
		user2.save()
 
		user.delicious_set.create(username="test", password="test")
		fixture = user2.delicious_set.create(username="test", password="test")
 
		self.assertEquals( fixture.user.id, user.id )
		self.assertEquals( UserNormalisation.objects.get(sub_id=user2.id).main_id, user.id )
		self.assertEquals( fixture.user, user )
 
	def test_normalisation3(self):
		user = pUser()
		user.save()
		user2 = pUser()
		user2.save()
 
		user.delicious_set.create(username="test", password="test")
		fixture = user2.delicious_set.create(username="test", password="test")
 
		norm = UserNormalisation.objects.all()
 
		Concepts.relate(user=user2, concept1="tag1", concept2="tag2")
		relation = ConceptRelation.objects.filter(user=user2, concept1="tag1")[0]
		self.assertEquals( relation.user.id, user.id )
		self.assertEquals( relation.user, user )

Take special note to the latter two examples. In test_normalisation2 you can see that when a delicious_set is created for user2, the two users become the same thing because both we’re using the same delicious username both times. Something similar happens in test_normalisation3, but there we see that creating a ConceptRelation for user2 actually creates it for the first user because they both behave as if they were the original user.

Tags: , , , ,

18
Jan

Python multiprocessing is fucking sweet

   Posted by: Swizec    in Uncategorized

CRAY-1 (no longer used, of course) displayed i...
Image via Wikipedia

You know how it is said every programmer needs to learn how to do parallelisation and funky stuff on multi-core multi-processor beast of machines? And how such machines aren’t even really beasts these days, they’re our run of the mill desktop and portable computers.

This is the world we live in.

It’s getting worse by the hour!

Very soon the first thing a young programmer will hear out of a lecturer’s mouth will be Thread-Safe.

But there’s something we can do about that even today. First of all, we can kiss threading good bye. Sure it’s sweet and yes it sort of works. But ew! It’s like trying to make a marine corps do their job with everyone’s finger in someone else’s arse. That’s the problem with threads you see, they keep picking each other’s arses and noses and then nobody can do any work.

Multi processing to the rescue!

Running an algorithm in several processes is the only thing that makes it run on several processesors in parallel and it gives each process its own memory space and everyone is nicely contained in their own little world. But fuck, now you can’t exactly pick another process’s arse when you need to … like when eating through a common queue of tasks.

And then python’s multiprocessing module, library, thingy, whatever it’s called, comes into play.

It. Just. Makes. Everything. So. Fucking. Easy!

This weekend I was working on a scrobbler for Delicious. Basically this thing is supposed to go through a user’s Delicious history, scrape every website it finds, send the results to three different semantic API’s and build connections between the tags those API’s return and the ones the user used to tag the particular link.

Now obviously there’s a lot of downtime involved here for every iteration. You’re easily looking at 10 solid seconds of waiting per website. This means that scrobbling 838 pages (my stress test) would take about two and a half hours. With multiprocessing it took something like 20 minutes.

The beauty of this approach is that I’ve never ever ever done anything in parallel. And yet I could do funky things like worker pools, queues, semaphoring and a bunch of other stuff I’ve only heard of in fairy tales until now … in an hour.

So there you go, an investment of a few hours for learning from scratch and some tweaking to create a ten-fold increase in speed.

Reblog this post [with Zemanta]

Tags: , , , , , , , ,

28
Dec

These are the times I love my job

   Posted by: Swizec    in Insanity

Today I spent five solid hours programming (so far) and didn’t write a single line of code, nay, not even a single character. All I did was think with the whiteboard.

Eventually covering about 15 square meters of whiteboard in squiggly lines and weird characters and all sorts of stuff that I probably shouldn’t explain in too great a detail publicly. Let it suffice to say that I believe to have solved the problem of translating machine vocabulary to personalised user vocabulary.

IMG00137IMG00135IMG00133

Reblog this post [with Zemanta]

Tags: , ,

7
Dec

Heaven is where your code lies

   Posted by: Swizec    in Inspiration

Here I am at Hekovnik, alone in the romantic ambient of spotlights, whiteboards and loud music that makes me just wanna code code code. Yep, it’s Iron Maiden, felt like it, and son, I am not disappoint.

Romantic ambient

Lounging on the sofa, with my trusty MacBook in lap, shiny logo greeting anyone daring to enter my bubble of deep concentration and flowing code masterpieces.

IMG00077

It’s time like these that I truly love what I do, I know us developers are a fussy bunch and like to get all up in arms over the littlest thing that upsets us. That we love nothing better than to nag about some app or another taking 10 fucking milliseconds too long to open! The travesty!

But fact remains, I love being programmer, despite stupid tests not passing, despite frequent choices not to use testing that end up biting us in the arse, despite always changing design specs, despite all the bugs and all the weird shit and that little typo that brings the whole system to its knees and takes a week to fix …

heaven really is where your code lies, because code is an expression of one’s self, because code is art and no matter what anyone ever says, I will continue to see myself more as a poet than an engineer.

Reblog this post [with Zemanta]

Tags: , , ,

When I took a break from php three months ago I’d been up to my shoulders in the technology for about five years – I remember my first interactions with the language were figuring out whether I need to use .php3 or .php4 or just .php file extensions. But that’s not very interesting.

A more interesting tale to tell is perhaps how for the last few months I was growing increasingly frustrated with my job, my work environment, my skills toolkit and simply the whole LAMP web development stack. It was time to take a break … it was a lot later that I discovered a cool TEDtalk on the topic, watch:

But anyway, onwards to what I’d learned.

Lessons that can only be learned by staying the fuck away

This week my PHP hiatus saw the beginning of its end, I had to get a freelancing job to pay bills and other such nuissance – since PHP and Javascript seem to be what I’m most popular for in the community that’s the easiest thing to get a job for. And to be honest, I’m not really fluent enough with anything else to do it for real money.

So earlier this week I had a meeting with the team lead of the project to give me a short tour of their, dare I say it, very well designed framework, and I realised how much extra work needs to be done by the framework just because PHP is such an incredibly lame language.

  1. PHP doesn’t have support for that thing where you can use objects right out of a function. So we need a getScalar, getString, getRows, getRow function instead of a lovely getValue, “”+getValue(), getRows() and getRows()[0] system. Why php, WHY don’t you support this?
  2. PHP also can’t do inline arrays, objects and tuples. This is great for passing data around in a descriptive way and PHP fails completely. Why can’t I do a return { x: 0, y: 100 }? Or something like that? It’s silly that I’d have to create a whole new Vector class that doesn’t do anything other than hold two values.
  3. Another thing PHP desperately needs are keyword arguments, or whatever they’re called. It should be possible to call a function that has default values and define specific arguments without having to define all the other arguments because the one I need to set happens to be last. Seriously, what if the defaults suddenly change? Do I go through all the code to pass the correct defaults for that one argument I actually need? This could be solved by passing an object around but what’s this? Objects are a pain to create? Right …

So I guess that makes for almost one thing I’ve learned per a month of abstinence. Not the best ratio by all means, but it’s silly to find that such a modern language used by so many people would be such an utter failure on many points others, not unlike Lisp, have solved half a century ago. What the flying fuck!?

Did I miss anything? What else does PHP do well and what does it do poorly?

Reblog this post [with Zemanta]

Tags: , ,

4
Aug

The ten pros and cons of unit testing

   Posted by: Swizec    in Uncategorized

Last Act of the Fallen
Image by ecstaticist via Flickr

Some of you may remember my writing about how unit testing is anti-productive and those of you I have to disapoint, I still dont’ think it’s the best productivity tool out there.

BUT!

The past few days I had another go at unit testing while developing a “server” for gathering statistics on how people use Twitulater. This was mostly in preparation for making a “server” for syncing Twitulater users, more on that some other day, it was mostly a learning exercise.

What I learned was that:

  1. Unit testing is no guarantee for quality (con)
  2. Unit testing can be really cumbersome to use and more time can be spent finding a test than solving the problem. Like for example: How do you test an app that reads from sys.stdin? (con)
  3. Unit testing only helps with bugs you’ve anticipated or found (con)
  4. Unit testing can quickly lull you into a false sense of perfection (con)
  5. Unit testing is a life-saver when you’re refactoring (pro)
  6. Unit testing is extremely gratifying – nothing better than finally seeing all those tests pass after a long night for a sense of achievemt (pro)
  7. Unit testing feels easy to use after the tests are written (pro)
  8. Unit testing provides repetitive and verifiable measurments – the scientific method(pro)
  9. Unit testing is great for verifying behaviour under strange conditions – very easy to test for sturdines against idiocy - (pro)
  10. You quickly learn to love it (pro)

So there you have it, four cons versus five pros. I guess unit testing actually is good and I am forced to somewhat eat my words … but I still think it should be easier to do integration testing. Sure, very easy to mimick an input straight to an object. But how on earth can you test an application actually reads input as expected?

Or, how exactly do you test the output of something? Just because all the return values are correct, doesn’t mean the actual output is as well. And what about GUI’s? I would love to have a way of testing my GUI looks like I expect it to without having to keep reruning the application … ideally, unit testing would be so good that after the tests pass I can be certain everything works and ship it without ever having run what I’m working on. But I don’t think we’re getting that any time soon.

Reblog this post [with Zemanta]

Tags: , , ,

23
Jun

Unit testing is anti-productive

   Posted by: Swizec    in Uncategorized

Salish Mist
Image by ecstaticist via Flickr

Today I finally got my feet wet with something I’ve been meaning to try on for size ever since reading Clean Code, during my trip to Vienna last autumn; wow has it really been that long already, where’d winter and spring hide?

Anyway, so at about midnight last night I finally embarked on the process of coding up a new feature for Twitulater, or at least its server-side bits, after some prep work. Now since this is a rather mission critical system that I’d very much like to be somewhat reliable and rock-solid, unit testing seemed to be the way to go.

Downloading PHPUnit gave me some headaches, because ubuntu’s package managers fucked something up. Why is it I can’t install Pear if there are broken packages for something completely different? Then came the figuring out of how to actually do unit testing and I must say, it was incredibly simple. Of course I did have eight months’ time for the principles grokked from Clean Code to seep in, but still.

Mostly I was suprised to finally confirm that I have been doing test driven development (TDD for you acronym junkies) for a long while. Just in reverse. Whereas now, with automated unit tests, I first write a test, then the code, I used to write the code then test the hell out of it. With PHPUnit testing has become much less of a hassle – run a command, make sure everything works. Nice!

However, unit testing has one large drawback. It took me a solid six hours of coding to produce … nothing. I have in my possession now 200 lines of real code that doesn’t implement much other than making sure users exist and authenticating them, and a bunch of tests taking up a full … 170 lines of code. This is of course after some refactoring and whatnot, the original ratio was always that there were twice as many tests as there was actual code. Yummie.

Now I’m sure many of you will bash me for being such a dirty little blasphemer, but fuck it. Despite all the headaches saved with testing, despite making testing a lot simpler and quicker. It still took me SIX BLOODY HOURS to create some functionality that never used to take more than two hours to code and debug.  This is quite horrible.

And to top it all off, I can’t even be certain there are no bugs in my code! I’ve reached the exact same level of debugged code as I normally would, except that now I can automatically test for everything I could think of going wrong, whereas before I had to invest a bit of elbow grease.

Then again, I probably won’t be abandoning unit testing for mission-critical things any time soon. There is a sense of gratification seeing the tests pass, there is also a sense of “oh my god that was easier than eating a pie” when you run 20 tests and it takes ten seconds instead of ten minutes.

Perhaps most importantly, however, is that with automated unit tests you never forget to run a test. So I guess, in the end, it’s worth it spending those extra long hours to have code you can prove works like you think it should any time. Without spending a bunch of effort on making sure it does.

Unit testing is here to stay, even if it’s a bit of a pain in the arse.

Reblog this post [with Zemanta]

Tags: , , ,

6
Jun

Slovenia php conference day2 (live blogging)

   Posted by: Swizec    in Uncategorized

10:16 Today was horrible walking weather. Groggily stumbling to IJS felt a bit like trying to swim through a sauna. I don’t even know how late I was getting here, but I somehow managed to snatch the very last energy drink. Yay! Shame I’m in last row this time … think we’re listening to @markostamcar talking about … something. Is this the “code snippets that saved my life” talk?

Smoke sauna in Enonkoski, Finland.
Image via Wikipedia

Oh and before anyone asks again, yes, I’m the guy in a black bowler and no that card is not an Ace. Never an Ace.

10:29 @markostamcar just admited to being a dirty dirty pirate thief. Wonder if anyone from the MAFIAA is here or we’re all just a bunch of dirty swashbucklers? Interesting code bit, think it calculates a foreign TV guide into local time for torrent browsing.

10:34 Interesting thing I just noticed. Trying to make fancy <?phpconference in a blog title makes wordpress do funny things like simply cutting everything ahead of <? off. Couldn’t you please just escape it? It felt lovely having it there and now my url is all funky.

10:51 Miha Hribat made a refreshing commercial break for igrajmo.se, whatever that is. Looks interesting, but the talk will be about caching dynamic content. Hopefully we’ll all learn something new even though most of us have probably dealt with this before.

10:58 MogileFS is an opensource filesystem written in perl that runs on the application level and, apparently, uses everything from the DB, disk system and some other funky stuff to keep data safe and bloody quick to access. Sounds very nice. And now the more interesting part about memory caching – the really important thing when it comes to cache. Oh hey, I just noticed a corporate-approved dry joke. Well done!

11:03 Yes memcached! The greatest thing since caching was invented and of course, all the big names are using it. Been a while since I played around with this thing, should probably try it again. Miha says the biggest object you can store is 1MB in size and since Twitter complained about having a problem with one of their important objects exceeding 1MB I’m concluding twitter uses memcached as well … oh hey I didn’t know memcached will only keep things for at most 30 days.

11:35 Anze Znidarsic will be talking about abusing flash+php to make rich internet applications. And he just received a raging applause for giving us a 15 minute break :D Win.

11:54 Anze is talking about Flash on the internets, what we can and what we cannot do. Personally I hope flash dies a quick death and we shouldn’t be abusing it to do new things like we did with pdf. Sure it’s difficult to make things work the same in every browser, but we don’t HAVE TO. What we need to do is teach users that things won’t look the same everywhere, even native desktop applications don’t look the same on everyone’s computer.

12:01 According to what is being said I’m really going to need to look into this Flex Builder thing. It’s quite ama

As Seen on Television album cover
Image via Wikipedia

zing how, apparently, you can just design something in Photoshop, export and then just add some working logic and you’re done. Looks incredibly simple and like a very fast workflow. Lovely bit is how I can abuse this lecture to pretty much deal away with half the things I could have said on my talk in a few hours. Brilliant! Thanks Anze.

12:11 That is a wonderfully brilliant sample app. Basically a project managment tool for girls. Stores girl_id and her status that is one of “Done”, “to-do” or “in progress”. Today is definitely much better than yesterday was.

14:06 We’re back from lunch and Mr. Somebody, didn’t catch his name, is talking about Comet, which is apparently a method for pushing data from server to client and doing it live. This is something I’ve always wondered about so I’m about to have my wet dream answered.

14:12 Comet is interesting. Apparently it’s some sort of reverse Ajax and once more isn’t a technology in and of itself (just like Ajax) but an architecture design. HTTP/1.1 allows us to do this crap and even though all of this is starting to make a little sense it’s quite odd. It’s polling, but not polling, or is it polling? Damn, can’t wait for the practical demo. (Oh the guy is Mitja Kramberger, cool guy)

14:20 There almost seems to be more problems with Comet than it provides solutions. Interesting. Since I’m not actually

Image of Robert Basic from Twitter
Image of Robert Basic

understanding a whole lot of this (thanks @robertbasic for giving that wikipedia link) there isn’t much summation I can do for you blog readers. Sorry. Or maybe I’m just not paying enough attention since nervousity is building up ’cause I’m up next. Whose stupid idea was it anyway to get over public talking anxiety by talking publicly a lot? Idiot.

14:31 Comet on the server is where it gets really interesting. Traditional server software is #fail because you need man concurrent connections and they’re made to quickly close everything and get on with their lives. Someone should implement an event-based IO, but nobody’s really done anything yet, working on it, just not done. So when somebody DOES make something, will the web be all buzzy and broken and fubar and odd as it was when Ajax first became popular?

14:35 I was wrong. There are many implementations … makes me wonder why not everyone is doing this just yet like they did with Ajax? Poor gecko browser support? Developer ignorance? What?

16:00 Wow, I’ve never had so much fun talking in front of a large crowd for 45 minutes before. Not sure what it was, but I simply blabbed my mouth off. There were even questions when I finished! Yay. Anyhow, seems we’ll be listening to Tomaž Muraus talking about the CodeIgniter framework. @anze_znidarsic was right, we should have a large discussion over frameworks and slug it out in the mud.

16:15 Blahblahblah CodeIgniter, blahblah, use frameworks, blahblah, MVC is awesome, blahblah, frameworks are fast

or slow … this talk shouldn’t take place as last because it’s going to stick with us too much and it’s quite probably one of the less great we’ve seen these two days. Too bad the organisers can’t tell in advance how interesting someone will be as a presenter. Not everyone of us is Gašper Kozak.

16:35 Let me give you some quotes from the twitter stream of what’s going on right now.

{{legend|#ff0000|1930 to 1939}} {{legend|#ff54...
Image via Wikipedia

@janhancic zzzzzz

@alesf: I want to know why should I use CodeIgniter not how.

@anzerobida: Codelgniter prezentation is really not interasting:( Just waiting for Android!

@deveti: lahko bi bli kaki praktični “live” primeri uporabe codeigniterja … preveč teorije :/

and so on. Really, really is a shame this will be last. Those five minute quick persentations better be good and interesting.

16:55 Lightning talks now, hope they’re as interesting as the barcamp ones usually are. First one … no idea, looks marginally interesting. I like the zen-like slides. Nice and clean, just like my very own barcamp lightning talk a while ago.

17:04 Apparently at the party last night were two gym trainer people and now they’re here talking about http://www.ls-trenerstvo.si, and by god that’s one hot chick on their frontpage. Since I see one of those guys at the gym all the time, and they happen to be aksing about SEO, would be nice if they could be my trainers and I could be their SEO guy. Hmmm … (that chick is really good SEO by the way)

17:09 talcho.com is a webservice thingy for chatting and even for gameplaying. They’re supposedly also developing an integrated client for embedding in any website and whatnot. Wonder if they use Comet, should ask when he’s done talking.

17:13 sweetsurveys.com five minute talk feels a bit silent. Must say I’m choked to see the guy can’t type on a mac keyboard, funny. And I am very impressed they have a certificate that actually shows up as green in firefox! Bravo! But a good pitch this isn’t. Oh well, still seems like a cool enough service I guess.

17:19 This guy is young, very young. But by god he’s great at just pushing and pushing and pushing his stuff on us. There isn’t a barcamp he doesn’t talk at, there isn’t a conference he doesn’t talk at. He’s gotten better and more fluent too, bravo Jan! Bravo! Anyway he’s talking about ig33k.si whatever that is. Looks pretty.

I think a few years down the road a shrewd businessman will come out of this curly-haired little dude.

17:32 Awww, I didn’t win an Android G1. :(

Reblog this post [with Zemanta]

Tags: , , , , ,

Adobe AIR
Image via Wikipedia

Some days ago when I was developing a plugin interface for Twitulater I came upon an interesting and seemingly unsolvable problem in the way Adobe AIR brainlessly tries to make everything more secure – eval function simply doesn’t work. Even if you use it, nothing happens.

Alright so there is no eval for evaluating dynamically created javascript. No problem, I’ll just use some sort of include function Adobe has surely implemented since AIR is supposed to be this awesome development platform and we all know the ability to include files is somewhat paramount to serious development.

But what’s this? Even in AIR 1.5 there STILL isn’t an include? What the fuck! Ok, sure, I do realise that they provide an include with Flex, but to be honest Flex isn’t exactly something I want to use because the way variable types are postfixed to the variable name fucks with my brain and makes me feel dyslexic. Seriously Adobe, what WERE you thinking there?

Anyhow, back to lack of eval. Adobe claims that eval is an evil funciton people use to evaluate unverified code from third party API’s and thus make their applications superbly vulnerable to an injection attack. Naturally this is a very valid reservation, but I think the solution is severely flawed since it introduces more problems than it’s worth.

Basically everything they’ve done is force bad developers to use a JSON interpreter of some sort for their third-party stuff. Which makes sense, it’s a little bit slower than eval, but at least no code gets executed since functions and objects produce errors. Great, no executable third-party code. But did this really solve anything? Oh no wait, bad developers will still open their application up to many security flaws and everyone else is more than slightly inconvenienced.

I could understand if Adobe at least put a JSON compiler or some sort of dumbed down eval into their javascript API, but no, they just leave us out to dry. And, surprisingly, none of the jQuery include plugins out there actually work, neither does javascript MVC’s include function. At least I haven’t been able to make them work.

But there is in fact a way to include all files from a certain dir, it’s a very fucking ugly hack and using it made my programming heart convulse in pain. See for yourself:

	PluginLoader.prototype.loadPlugin = function ( pluginDir )
 
	{
 
	        if ( this.shouldLoadPlugin( pluginDir ) )
 
	        {
 
	                var files = pluginDir.getDirectoryListing();
 
	                for ( var i in files )
 
	                {
 
	                        var file = files[ i ];
 
	                        if ( file.extension == "js" )
 
	                        {
 
	                                this.loadFile( file );
 
	                        }
 
	                }
 
	                this.addLoadedPlugin( pluginDir.name );
 
	        }
 
	}
 
	PluginLoader.prototype.shouldLoadPlugin = function ( dir )
 
	{
 
	        return dir.isDirectory &amp;&amp; dir.name[0] != '.';
 
	}
 
	PluginLoader.prototype.loadFile = function ( file )
 
	{
 
	        var stream = new air.FileStream();
 
	        stream.open( file, air.FileMode.Read );
 
	        var script = stream.readUTFBytes( stream.bytesAvailable );
 
	        stream.close();
 
	        document.write( "" );
 
	}
 
	PluginLoader.prototype.addLoadedPlugin = function ( pluginName )
 
	{
 
	        document.write( "" );
 
	}

As you can see it relies on injecting HTML javascript inclusion into the head after itself and thus ensuring AIR evaluates it. If you try injecting in any sort of nicer way like with appendChild or whatnot, it doesn’t work. And the catch is this code has to be run before the document is loaded beyond the head and I think it actually makes AIR spout an error of some sort. But it works.

Reblog this post [with Zemanta]

Tags: , ,