Writing A Calendar App In Rails Vs. PHP

Some time ago, I wrote a web-based calendar application in PHP, one of my favourite programming languages. This tool would produce a HTML tabular calendar for a four week period, Monday to Sunday, in which the current date (or a user-specified date) fell in the second week (so you’re looking at this week, last week, and two weeks in the future). The user-specified date, for various reasons, would be provided as the number of seconds since the epoch (1970). In addition, the user must be able to flick forwards and backwards through the calendar, “shifting” by one or four weeks each time.

Part of this algorithm, of course, was responsible for finding the timestamp (seconds since the epoch) of the beginning of “a week last Monday”, GMT. It went something like this (pseudocode):

1. Get a handle on the beginning of "today" with [specified time] modulus [number of seconds in day]
2. Go back in time a week by deducting [number of seconds in day] multiplied by [number of days in week] (you can see I'm a real programmer, because I set "number of days in week" as a constant, in case it ever gets changed)
3. Find the previous Monday by determining what day of the week this date is on (clever functions in PHP do this for me), then take [number of seconds in day] multiplied by [number of days after Monday we are] from this to get "a week last Monday"
4. Jump forwards or backwards a number of weeks specified by the user, if necessary. Easy.
5. Of course, this isn't perfect, because this "shift backwards a week and a few days" might have put us in to "last month", in which case the calendar needs to know to deduct one month and add [number of days in last month]
6. And if we just went "back in time" beyond January, we also need to deduct a year and add 11 months. Joy.

So; not the nicest bit of code in the world.

I’ve recently been learning to program in Ruby On Rails. Ruby is a comparatively young language which has become quite popular in Japan but has only had reasonable amounts of Westernised documentation for the last four years or so. I started looking into it early this year after reading an article that compared it to Python. Rails is a web application development framework that sits on top of Ruby and promises to be “quick and structured”, becoming the “best of both worlds” between web engineering in PHP (quick and sloppy) and in Java (slow and structured). Ruby is a properly object-oriented language – even your literals are objects – and Rails takes full advantage of this.

For example, here’s my interpretation in Rails of the same bit of code as above:

@week_last_monday = 7.days.ago.gmtime.monday + params[:weeks].to_i.weeks

An explanation:

  • @week_last_monday is just a variable in which I’m keeping the result of my operation.
  • 7.days might fool you. Yes, what I’m doing there is instantiating an Integer (7, actually a Fixint, but who cares), then calling the “days” function on it, which returns me an instance of Time which represents 7 days of time.
  • Calling the ago method on my Time object, which returns me another Time object, this time one which is equal to Time.now (the time right now) minus the amount of Time I already had (7 days). Basically, I now have a handle on “7 days ago”.
  • The only thing PHP had up on me here is that it’s gmdate() function had ensured I already had my date/time in GMT; here, I have to explicitly call gmtime to do the same thing.
  • And then I simply call monday on my resulting Time object to get a handle on the beginning of the previous Monday. That simple. 24 characters of fun.
  • + params[:weeks].to_i.weeks simply increments (or decrements) the Time I have by a number of weeks specified by the user (params[:weeks] gets the number of weeks specified, to_i converts it to an integer, and weeks, like days, creates a Time object from this. In Ruby, object definitions can even override operators like +, -, <, >, etc., as if they were methods (because they are), and so the author of the Time class made it simple to perform arithmetic upon times and dates.

This was the very point at which I feel in love with Ruby on Rails.

Magic Story

Inspired by Andy‘s PassThePageGame on the RockMonkey wiki – a collaborative storytelling game based on that silly game you used to play at school, I’ve written my own tool:

MagicStory is a collaborative wiki storytelling tool designed to be harder to “run away” with than normal wikifiction. Having read the story, participants can write a suggested “next sentence”, and after three suggestions have been collected a fourth person will be able to choose which one is used. Give it a go!

You’ll need a RockMonkey account, of course, but they’re free and simple to set up.

Rock Exchange

This weekend I hope to release Rock Exchange, my latest WikiGame on the RockMonkey wiki. I’m just finishing performing some tests and fine-tuning on it now. Here’s a screenshot:

Rock Exchange game on the RockMonkey Wiki

In Rock Exchange, players will be able to invest their hard-earned Rocks (a unit of currency) in shares in the various pages on the RockMonkey wiki. The value of these shares will fluctuate based on several characteristics, and players will have to play the odds in order to know when to buy and when to sell to gain a return on their investment. A page’s shares fluctuate based on:

  1. Popularity: so if a new page seems likely to attract the attention of a lot of passing Googlers, it’s worth investing in, whereas an “in joke” that’s died out is not. Similarly, players can manipulate wiki page links in order to attract interest. The most valuable indicator of popularity is how many people come to the site for the first time, entering on a given page.
  2. Investment: investment in pages will put positive pressure on their value, but selling shares damages this value by flooding the market – who’ll be first to pull out of a high-flying page, thereby forcing other shareholders to suffer?
  3. Interference: there will be several methods for people to drastically interfere with the value of their shares and the shares of the other traders, but these won’t necessarily be immediately apparent.
  4. Random factors: the rock market, like the stock market, is an unpredictable animal, and there’ll be a small amount of luck in any investment.

The game’s pretty much “ready-to-play” in it’s most basic form right now, but I want to run it alone awhile longer and see if I can improve the balancing factors in it.

×

OpenID For WordPress

Update: 12th October 2007 – this project is to be considered abandoned. Please see How To Set Up OpenID For WordPress Comments instead. Thanks for the support and for your interest in OpenID.

THIS IS ALL HORRIBLY OUT OF DATE. THE DOWNLOAD LINKS DON’T WORK, I KNOW. GET OVER IT. More seriously now, I am working on a new version of this that actually works as a WordPress 2.0.x plugin. It’s very nice, but it’s not finished. Watch this space. In the meantime, why not take a look at OpenID Comments For WordPress (which is based on my preliminary work, here). Thanks for all the attention, guys.

As promised, I’m releasing the first usable version (v0.4) of my WordPress OpenID plugin tool. It’s very, very messy and a little buggy. Plus, installing it requires that you hack a few PHP files… use at your own risk. You’ll need a WordPress v1.5 weblog. Download this package and decompress it to your WordPress directory. It will create an openid_icons directory, a file called openid.php (the main codebase), and a file called openidform.php (the form that appears on your blog). Edit openid.php and substitute your own weblog URL in at the appropriate places (near the top). Link in the login form wherever you like. I’ve done so in my theme’s “sidebar.php” file, with the following code: <?php include (TEMPLATEPATH . '/openidform.php'); ?> In your main index.php, add a line to include the openid.php file. This will allow logins and logouts to be processed. Something like this: <?php require_once('openid.php'); ?> In wp-comments-post.php (the comments processor), substitute the following code in under “// If the user is logged in”: // If the user is logged in get_currentuserinfo(); if ( $user_ID ) { $comment_author = addslashes($user_identity); $comment_author_email = addslashes($user_email); $comment_author_url = addslashes($user_url); } elseif ($_SESSION['sess_openid_auth_code'] != "") { $comment_author = addslashes($_SESSION['sess_openid_auth_code']); $comment_author_email = "openid@example.com"; $comment_author_url = addslashes($_SESSION['sess_openid_auth']); } else { if ( get_option('comment_registration') ) die( __('Sorry, you must be logged in to post a comment.') ); } Notice the extra section, relying upon $_SESSION[‘sess_openid_auth_code’]. That’s the magic bit. And it should ‘just work’. Let me know if it doesn’t; I’ll be improving the codebase over the coming weeks and I’d like to include your suggestions. If you need any help setting it up, I can probably help with that too, or even with adapting the code to work with other applications (than WordPress). Features so far:

  • Authenticate OpenID users
  • Easily authenticate OpenID users from particular servers, including members of LiveJournal, DeadJournal, and Level9
  • Authenticated OpenID users can post comments

Features to come:

  • Cookie-based “remember me”
  • Ability to authenticate WordPress users (e.g. the weblog owner) by an OpenID
  • “Friends Only” protected posts, which can only be read by certain authenticated users
  • AJAX-powered log-in (to save users from having their browsers redirected excessively, and because it can be made to look swish), where supported

If you want to help code, just drop me a message.

OpenID And Scatmania

Over the last few weeks I’ve playing playing with an exciting new technology known as OpenID. Do you remember Microsoft Passport and it’s opposite number, Liberty Alliance? Well; we all know that these services weren’t all they cracked up to be. They claimed to be “distributed log-on services”, but in actual fact they were centralised log-on services (controlled, for example – in the case of Passport – by Microsoft – do you want Microsoft to know everything you do on the web?), and not really distributed at all…

…OpenID really is a distributed log-on service. Anybody can set up an OpenID server and start giving out OpenID accounts. If you have a weblog with LiveJournal, for example, you already have one, and soon folks on other similar blogging services will have them too.

I’d love to see a future where OpenID catches on, because it really is a beautiful and elegant (from a technical point of view) way of doing things, and it’s really easy to use from a user’s point of view, too. I’ve spent a little while implementing the beginnings of a WordPress (the blogging engine that powers this site) plug-in, and it’s taking shape: if you look in the upper-right of the page, you should find that you’re able to log in to this web site using your LiveJournal account. That means that WordPress users like myself, in future, should be able to do things like LiveJournal’s “friends only” posts, and allow LiveJournal users to make comments in a way that proves they are who they say they are, and many other benefits, too.

But, of course, it doesn’t stop there: DeadJournal will be next. Then TypePad. Then Blogger and the forum sites – phpBB and the like. Then the wiki sites. All of these sites will be able to authenticate against one another, and make content private, or accessible, without having to have silly “sign up” systems of the type we’re starting to see everywhere these days.

It’s all very exciting, but it’s early days for now. Right now, my WordPress plugin doesn’t do a lot – you can log in and out, and that’s about it. But give me a go, and tell me what you think – log in to my blog using your LiveJournal account, and give me some feedback. And when I finally get this code to a production level (right now it’s buggy as hell), I’ll release it as a WordPress plugin, and the world will be great.

Peekaboom!

This game is so much fun: Peekaboom!

You are paired up with a random other player. For each round, one of you is a “peeker” and the other is “booming”. The boomer has a photograph in front of them and a word that associates with it (e.g. “balls”, “men”, “cooking”, “elephant”). They can click on parts of the picture to expose them to the peeker. The peeker has to guess what the thing depicted is. If the peeker gets it right, both players get points. The less of the picture was exposed, the more points the two get.

As the peeker makes guesses, the boomer can rate them as “hot” or “cold”, giving feedback to the peeker. The boomer can also pass limited clues in the form of “noun”, “related noun”, “verb”, etc. to the peeker. The players are against the clock to score as many points as possible before time runs out.

The really clever thing about this fun little online game is that it is being used as artificial intelligence research to teach computer algorithms how to spot the “important” parts of a picture: the bits that can be used to determine what the picture is of.

Give it a go, and contribute towards some AI research while you’re at it…

Microsoft SQL Server Versus FTP

This is a geeky post. You have been warned.

Microsoft SQL Server is one of those funky advanced database management systems that supports replication. One of even fewer that supports merge replication – where data edited and updated at two separate databases can be merged on a schedule and the changes reproduced at both ends, and any conflicts (for example, two different operators on different sites changing the same record in different ways) can be brought to the attention of an operator. This is very good.

Sadly, it’s not terribly well thought-out as far as anonymous internet replication is concerned. You see, it works wonderfully if the replicating servers are on the same Windows domain, but that isn’t always possible.

We’ve got a set-up where a client’s database engages in merge replication with a separate database on our web server. As the two servers are on different Windows domains, and because of restrictions in the firewall configuration, we’ve set up Microsoft SQL Server 2000 to perform the replication over the FTP protocol. Therein lies our first problem.

There is a bug in Microsoft SQL Server 2000 that prevents anonymous internet merge replication from working over FTP… unless you install Service Pack 3 or above… What the fuck? It took until the third service pack before they fixed this?

In any case, having fixed this, another problem rears it’s ugly head. Back in the dark ages (well, 1985), when FTP was first invented, we didn’t have firewalls. Not anything like the ones we do now, anyway. And so it made perfect sense for various technical reasons to make the FTP protocol work as follows:

Client connects to Server
Client: Hi there, Server.
Server: Hi there, Client.
Client: Can you send me file XYZZY, please?
Server: Sure can. Where to?
Client: Send it to my IP address, 1.2.3.4, on port 1026.
Server: It’s on it’s way…

When the internet suddenly became a nasty place, full of firewalls and NAT and proxy servers and restrictions, this didn’t work any more, because many clients wouldn’t accept incoming connections – they would say “send me it on port 1026”, for example, and would then refuse to listen on port 1026 (or a computer between them and the server would refuse for them). So we invented “passive FTP“, and renamed the old version “active FTP“, retrospectively. Passive FTP works like this.

Client connects to Server
Client: Hi there, Server.
Server: Hi there, Client.
Client: I’m a passive FTP client, by the way.
Server: That’s fine with me, so long as you aren’t also homosexual.
Client: Can you send me file XYZZY, please?
Server: Sure can. Because you’re passive, I’ll need you to connect to my IP address, 5.6.7.8, on port 1098.
Client: Am doing that now.
Server: It’s on it’s way…

And that works through even the most stubborn firewalls and all sorts of other restrictions. Wonderful.

For some reason known only to Microsoft, Microsoft SQL Server will not use passive FTP. And our client has a restrictive firewall. How Microsoft could have neglected to write into their program this most simple and fundamental bit of the FTP protocol is beyond me (Internet Explorer and several other Microsoft programs support passive FTP flawlessly).

Grr.

Abnib v2.2

Abnib now supports “feed hiding” of the “community” feeds (RockMonkey, Troma Night, Gallery). Just click the “hide feed” link at the bottom of a post of the type you don’t want to see. This feature by demand of Jon.

In other news, Blue Dragon is proving somewhat popular, with 7 registered players (plus me, but I don’t play on account of the fact that sysops who play their own games tend to do well, even if they’re not cheating, and get accused of cheating regardless of how well they do), and a couple more about to sign up. If you’ve not given it a go yet, there’s still time to get in and cause some damage before the “top players” pull too far out of reach… and if you are playing, you’ll see that a few new areas just became available to you…

Legend Of The… Blue Dragon

Following up my thoughts earlier about old-school online games, I did some investigation into what became of fab old games like Legend Of The Red Dragon. It turns out that there was an effort to revive this particular one as a web-based game called “Legend Of The Green Dragon”. Well; as it was open-source I took a copy and adapted it with heaps of suitable “Aberisms”. It’s Abniberific.

Click here to play Dan’s “Legend Of The Blue Dragon”

Feedback appreciated. Usual address.


Additional: In answer to a much-anticipated question – when playing Blue Dragon, you’ll only have so-many turns in which to do things each “day”. However, there are two Blue Dragon “days” in each “real world” day: midnight in Blue Dragon will be occuring at (about) midnight and mid-day (GMT) each day, and between those times you have all the turns you need to do things in the game world.

What Is A Door And Why Do I Care

Geeky post with little value to most people: ignore if you don’t want to learn a little about the history of the BBS, “Doors”, and the subculture around them. This post is written for folks like Ruth, who seemed interested, and others, who seemed possibly-interested.

Before about 1994, even the few of us who had been on the internet hadn’t had much exposure to the (young, at the time) world wide web, but for a decade or more before then, there stood a great remnant of what had come before. And for years to come, still, when internet access was still something for which you paid both monthly and for your call time, and probably to a “local” rather than a “national” ISP, there was another option for getting your “fix” of cyberspace.

That fix was the network of independent bulletin board systems (BBSs) that existed across pretty much every Western country. The US was full of them – pretty much every small town had a young geek somewhere with a spare computer in his parents’ basement. And here in the UK, small BBSs flourished as their members logged on and off and passed files around over now long-dead protocols.

BBSs were small, usually-local, centralised computers with one or more modems (or even acoustic couplers – primitive modems that connected to existing telephone handsets using little rubber suction cups and “spoke” analogue signals to one another across the telephone lines), often operated by hobbyists. To connect to one, you would need to know it’s phone number, and lists of these could be found wherever geeks talked. You’d simply configure your dialler software to “connect” to the specified number, and, a few pips and squeaks later, you were in. A short registration process would give you access to message board, file trading facilities (ah; all that – ah; all that porn), live chat (on the bigger, multi-line boards), and sometimes even internet access – e-mail, newsgroups, etc. Later, some of the more successful BBSs would become ISPs, and some of these maintained a BBS, too, that provided software that you could use to connect to their systems. BBSs had all the benefits of the internet at the time – albeit with a smaller user base – but frequently also had a distinct local feel and a “community” sense of belonging.

Another feature that became quite popular on BBSs were the so-called door games. These were pieces of software installed onto the BBS server computer – usually games – which could be interacted with by the BBS server software through one of several standardised interfaces (e.g. Fossil, DOOR32). It’s almost certain that the writer of Wargames had seen door games in action before he wrote his “Global Thermonuclear War” game into the film script. A majority of these games – like the one in Wargames – allowed a single player to play against the computer, online, with perhaps a shared, centralised scoreboard that all players can access. Later door games allowed a degree of interactivity, sometimes even “live” interactivity, between the players who were playing the game simultaneously.

When I ran Dice BBS (from my bedroom at my mum’s house), I had a selection of door games running on it, selected for their inter-player interactivity: P:TEOS (space trading sim), Legend Of The Red Dragon and it’s underrated sequel (all from Robinson Technologies, who still write computer games to this day), and a MOO (an object-oriented MUD [multiplayer text-based adventure] often with an emphasis on social interaction [like a MUSH]). Later, after Dice BBS’s closure (the internet had become too ubiquitous; too cool; there was no need for it any more), I hacked Legend Of The Red Dragon 2 to pieces and wrote a Pascal front-end to allow it to be played in a protected network environment, developed L2:PC, and deployed it to the Preston College network, where it became so popular that several players rarely did anything else, and one person was even thrown off their course, their grades suffered so badly.

Nowadays, door games are a bit of a forgotten breed. The MUDs and the MUSHes grew up into the MMORPGs of today (think “World Of Warcraft”, “Everquest”, “Ultima Online”, “Puzzle Pirates”). The need for the other games to be played in a centralised manner was negated by high-speed internet links and modern, multiplayer games. But there are still special places where BBSs run (usually adapted in such a way that you can reach them using the telnet protocol, over the internet), and there will always be a home for them in the hearts of those of us that lived aboard them.

Thanks for listening to a bit of nostalgia.

Further reading:

An Interview With Gary McKinnon

There’s a stunning interview you can listen to on BBC World Service with Gary McKinnon, the Briton who hacked into US military and research computers in order to hunt for evidence of UFO activity. In the interview he talks about how he did it, what he found, and how he was caught, as well as his feelings over the fact that he may be extradited to the US for up to a 70 year prison sentence for something which, in the UK, he couldn’t get more than four years. It’s well worth listening to. You’ll want a copy of Real Alternative installed (like Real Player, except good).

This Looks Promising

Hmm… my blog works. On it’s new host.

This looks promising.

More when I have it.

KnightmareWikiGame

My upcoming RockMonkey WikiGame is set to impress, I hope: I’m aiming for the most adventurous WikiGame ever created. There’s a screenshot available of the kind of thing I’ve got working so far. Probably a few weeks from completion, though.