Get the last day of the month in PHP

Posted on May 15th, 2012 | no comments

A super-easy function to get the last day of the current month

$lastDayOfMonth = date("t");

The "t" character actually represents the number of days in the current month – but that’s the same as the last day of the current month, so that’s that!

Tags: , , , , , ,

Latest CirrusNote Website

Posted on May 6th, 2012 | no comments

I’ve been slowly working on revamping the look and feel of CirrusNote for the last year or so. The latest incarnation of the website features a fully functional signup page for a free account, and a new clean design that showcases the Windows Client.

Behold!

Screenshot of the latest version of the CirrusNote website

Screenshot of the latest version of the CirrusNote website

A little more work and I might finally be happy with it :)

For anyone who doesn’t know, CirrusNote is a project I’ve been working on in my spare time to keep my brain active. It allows you to create notes and todo lists and sync them to the “Cirrus Cloud” so that you can access them from anywhere (anywhere with an internet connection that is…).

Right now, there is only a Windows client, but since the notes are stored as HTML, a web client isn’t a million miles away.

The API is built on Apache Thrift which I talked about in an earlier blog post. This will allow simple creation of new apps (iPhone, Android, Linux, Mac etc etc.) since the API can be used from any language with ease.

If anyone wants to help me test CirrusNote out, you can take a look at the new work-in-progress website (ignore the SSL Security warning), sign up and be added as a tester. Then you can download and try out the client and see what you think!

New Website: https://wdwarren.dyndns.org/cirrus (ignore the SSL Security Warning!)

 

Tags: , , ,

Awesome Database Design Tool: wwwsqldesigner

Posted on February 2nd, 2012 | no comments

I stumbled across this software while trawling the internet looking for good design tools. It’s super simple to use and looks great. Because it’s web based (written almost entirely in Javascript), you can design without having to have any gigantic software packages installed. Also it’s free and open-source which I’m always a fan of!

wwwsqldesigner in action

wwwsqldesigner in action

If you want to use it, it helps to have a web server to install it on, but it’s not mandatory. If you have a web server with a database server, you get the added bonus of being able to save your designs to the database using PHP and MySQL. If you don’t have a database server and/or web server, you can save the design as an xml file, and load it again super easily.

It’s hosted over at Google Code: http://code.google.com/p/wwwsqldesigner/

Tags: , , ,

SQL Script for Provinces and Territories of Canada

Posted on January 30th, 2012 | no comments

I made this simple SQL script to insert all the provinces of Canada. I’m posting it on here in case I need it in the future, and so anyone else that might find it useful can download it.

Get it here: canada_provinces.sql

Please forward any spelling mistakes or errors to me, or just comment on this post.

Tags: , ,

Ten Common Database Design Mistakes

Posted on January 30th, 2012 | no comments

I just read a really interesting article about database design mistakes. Check it out!

http://www.simple-talk.com/sql/database-administration/ten-common-database-design-mistakes/

My favorite quote would be:

In the heat of battle, when your manager’s manager’s manager is being berated for things taking too long to get started, it is not easy to push back and remind them that they pay you now, or they pay you later. These tasks pay dividends that are very difficult to quantify, because to quantify success you must fail first.

So true!

Tags:

When Spambots go wrong Part IV – Lonely Hearts

Posted on January 26th, 2012 | no comments

Another gem from my comment queue. This one is from a guy named “long island magician”.

How are you? Your site is great. Do you enjoy watching Movies?

Yes, I love watching movies. I also like holding hands and long walks on the beach.

Tags: , ,

Creating a public API with Apache Thrift

Posted on January 24th, 2012 | 1 comment

I recently came across a new client-server technology that really fascinated me. Through my meddlings with CirrusNote, I know that 49% of the effort of writing a good API is coming up with standards (XML formats, rules, schemas etc.), 49% is writing boilerplate code (XML parsing, schema validation etc. etc.) and the other 2% is spent actually writing interesting code like database interaction and cool client-side stuff.

Thrift is a software framework for scalable cross-language services development. It combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml. – From the Apache Thrift website.

Looking past the bizarre reference to OCaml, that sounds great. Reading the documentation (if you can find it) and browsing through the tutorials made me even more excited about Thrift. Some of the testimonials were also pretty inspiring (Evernote, Last.fm, Facebook (who actually invented Thrift) to name a few).

How does it work?

If you’re familiar with the concept of Interfaces in obejct-oriented programming, then you’ll have a pretty good grasp of how Thrift works already. The idea goes like this:

  1. Define your object types, constants, enums, services and methods in a special .thrift file
  2. Let thrift generate the server and client code for you
  3. You’re done.

Holy crap, I just gained 98% of my time back by not having to spend ages fixing stupid null pointer exceptions that are buried somewhere deep inside my XML parsing logic.

Okay, so I simplified it a little bit, however Thrift does do all of the heavy lifting for you leaving you free to concentrate on writing actual code instead of boring boilerplate junk.

Once you have completed step 2, you will be left with function stubs on the server side, allowing you to just fill in the blanks. On the client side, you will be left with an awesome, super-easy to use library that talks to your server seamlessly. When I say seamlessly I mean seamlessly. It’s as if you’re just calling methods inside some other class in your app.

The way I like to describe it is this: Thrift allows you to completely ignore the fact that the client and server are separated by the internet.

Getting down to code

To demonstrate the awesome power of Thrift, I’m going to implement a simple service on my web server (using PHP). Then I’ll show how to interact with that server from a basic client written in Python.

Note: A very basic knowledge of Thrift is useful to read/do this tutorial (i.e. read thisthis and this)

The Hello Service

The example I will use is a very simple service that just says Hello World in a few different ways.

First things first, we need to create a simple enum and a service. Open up a new file and call it Hello.thrift

enum HelloLanguage {
        ENGLISH,
        FRENCH,
        SPANISH
}

service HelloService {
        string say_hello(),
        string say_foreign_hello(1: HelloLanguage language),
        list<string> say_hello_repeat(1: i32 times),
}

FUN FACT: When Thrift generates your code for you, structs are typically translated into classesenums are usually translated into enumerated types and services are translated into interfaces.

Our new service interface describes 3 simple methods:

  • say_hello – this method will just return “Hello World!”
  • say_foreign_hello – this method will take a HelloLanguage and return a “Hello World!” in the appropriate language.
  • say_hello_repeat – this method will take an integer value and return a list of strings. The number of strings will depend on what you pass in.

For now, we’re done editing our thrift file. Honestly, that’s about 75% of the work done for creating a new API. Exciting stuff.

Generating the code

Now, we’re going to use thrift to generate the server code for us:

will@alaska:~/public_html/thrift/hello$ thrift --gen php:server Hello.thrift

Running the thrift code generator leaves us with a gen-php directory, which in turn contains all of the generated code. Because I specified the :server modifier on the thrift command, it also generated method stubs for our new service.

The code generator generates an interface. All we have to do to make the service work, is implement the interface, and override the methods.

In your web root, create an index.php with the following code in it:

$GLOBALS['THRIFT_ROOT'] = 'lib/php/src';

require_once $GLOBALS['THRIFT_ROOT'] . '/Thrift.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/protocol/TBinaryProtocol.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/transport/TPhpStream.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/transport/TBufferedTransport.php';
require_once $GLOBALS['THRIFT_ROOT'] . '/transport/TFramedTransport.php';

$GEN_DIR = 'gen-php';

require_once $GEN_DIR . '/Hello/HelloService.php';

class HelloServiceImpl implements HelloServiceIf {
        public function say_foreign_hello($language) {
                switch($language) {
                        case HelloLanguage::ENGLISH:
                                return "Hello World!";
                        break;
                        case HelloLanguage::FRENCH:
                                return "Bonjour tout le monde!";
                        break;
                        case HelloLanguage::SPANISH:
                                return "Hola Mundo!";
                        break;
                        default:
                                return "You didn't specify a valid language!";
                        break;
                }
        }
        public function say_hello_repeat($times) {
                $hellos = array();
                for($i=0;$i<$times;$i++) {
                        $hellos[] = "$i Hello World!";
                }
                return $hellos;
        }

        public function say_hello() {
                return "Hello World!!!!!!!!";
        }
}

header('Content-Type', 'application/x-thrift');

$handler   = new HelloServiceImpl();
$processor = new HelloServiceProcessor($handler);

$transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W));

$protocol = new TBinaryProtocol($transport, true, true);

$transport->open();
$processor->process($protocol, $protocol);
$transport->close();

Now we have a fully functioning HelloService implementation on our web server. Looking at the code you can see that I filled in the 3 methods I described earlier to produce the expected results.

Writing the Client

Our HelloService implementation is up and running, now we have to create a client to interact with it. I’m going to demonstrate in Python because it requires the least effort to get it going. I created a file called client.py and filled it with the following contents:

#!/usr/bin/env python

import sys
sys.path.append('gen-py/Hello')
import HelloService
from ttypes import *
from thrift import Thrift
from thrift.transport import TTransport
from thrift.transport import THttpClient
from thrift.protocol import TBinaryProtocol

try:
        host = "localhost"
        port = "80"
        uri = "/thrift/hello"

        transport = THttpClient.THttpClient(host, port, uri)
        transport = TTransport.TBufferedTransport(transport)
        protocol = TBinaryProtocol.TBinaryProtocol(transport)

        # create a new HelloService client
        client = HelloService.Client(protocol)

        # connect to the service
        transport.open()

        e = client.say_hello()
        print "say_hello() = %s" % e

        e = client.say_foreign_hello(HelloLanguage.SPANISH)
        print "say_foreign_hello(HelloLanguage.SPANISH) = %s" % e

        e = client.say_hello_repeat(10)
        print "say_hello_repeat(10) = %s" % e

        # close the connection
        transport.close()

# catch any errors
except Thrift.TException, tx:
        print "ERROR: %s" % (tx.message)

Using your service is as simple as creating a new client object, and calling the desired method. To run the client, we just execute the file and the following output is produced:

will@alaska:~/public_html/thrift/hello$ ./client.py
say_hello() = Hello World!!!!!!!!
say_foreign_hello(HelloLanguage.SPANISH) = Hola Mundo!
say_hello_repeat(10) = ['0 Hello World!', '1 Hello World!', '2 Hello World!', '3 Hello World!', '4 Hello World!', '5 Hello World!', '6 Hello World!', '7 Hello World!', '8 Hello World!', '9 Hello World!']

You can see that the first 2 methods just returned strings, and the third returned a list with 10 strings in it (because we specified 10 in the method call).

Conclusion

The HelloService is an extremely simple example, but it demonstrates how easy it is to call remote functions from a simple client with very little coding required. I barely scratched the surface of what Thrift is capable of. To see an example of a very complex thrift service definition, I suggest you check out the Evernote API reference. They make full use of namespacing, custom types, complex structs and so on.

Thrift makes cross-platform development very simple as well. Want to create a HelloService android app? Just run the thrift code generator to generate the Java code, and now you have access to all the service methods and types in your app. Want to write a Mac OS X client? Just generate the cocoa code and you’re able to call your services really easily with very little effort.

Further reading

 

Tags: , , , , , ,

New year’s resolution: Blog more!

Posted on January 7th, 2012 | no comments

We had an awesome holiday season here at the Warrens. There was much eating, drinking, laughing, jigsaw puzzles and PS3.

Highlights for me would include bringing home Jen’s very first ever REAL Christmas tree, just to find that; 1. There were spiders in it (which I swiftly vanquished) and 2. The stand we bought didn’t have a chance in hell of holding that leviathan of a tree up (~7 feet). After a quick trip to our friendly neighborhood Walmart, the tree was up, and everything was right with the world. I love the smell of real Christmas trees, it really puts me in the Xmas mood. Also, I’m pretty sure it made less mess than the fake one we used to have!

We also became the proud owners of a PS3 as well a slew of new games for it. After plowing the best part of 20 hours into Metal Gear Solid 4 (something I’ve been waiting to do since it came out in 2008), I’m playing through the Uncharted series. I also managed to find yet another function for my Linux server in the basement – streaming media to the PS3! I used Mediatomb and it works pretty well (especially transcoding 1080p blu-ray rips in real time!). Looks like all those movies on the file share aren’t going to go to waste after all :D . Between that, Netflix and the PS3 itself, I would say we’re pretty much set for the foreseeable future as far as entertainment goes.

New Year’s was great as well. We hosted our annual party, and some of our good friends came round. We ate and drank and played Cranium a lot – such an awesome game (especially when there’s booze involved :D ).

Among a few others, one of the New Year’s Resolutions I’ve made is to write on here more often, and to put more time and effort into it when I do. Other resolutions include: eat less, exercise more, see friends more often and work harder. Hopefully all these resolutions stick, but if they don’t, I’ve only got myself to blame!

Tags: , , , , ,