Internet Satire’s Cambrian Explosion

It used to be about re-cutting new trailers from old movies (see Something Blue for the ultimate). Now we’re getting completely original trailers for movies that never existed at all.

This is a really, really impressive video. Matt Damon was right: Sarah Palin’s life really is a bad Disney movie.

http://www.collegehumor.com/moogaloop/moogaloop.swf?clip_id=1831461&fullscreen=1

Fringe Show: Set List

Greetings Evildoers,

As occasionally happens, I have a show in Fringe. This time it’s an improvised musical show — we create a new band at that the beginning of the show from audience suggestions, and then play a whole gig as that band. The music is rehearsed, but the lyrics are improvised based on our interaction with the audience. It’s a truly unique new form of theater, and we really enjoy playing it.

Each week is a different genre, so you can come along to all 3 if you like! 😉

For this event we’ve assembled some of the finest improvisors and musicians in Melbourne to play our 3 debut genres: Folk, Jazz and Rock. We’ve got members of folk ensembles, orchestras, music theater shows, rock bands and more to create an improv supergroup that you will blow your mind.

The gigs are on Saturdays at 4:30pm at Trades Hall and run for about an hour:

  • 27th September @ 4:30pm: Folk
  • 4th October @ 4:30pm: Jazz
  • 11th October @ 4:30pm: Rock

Tickets are $15 full price, $12 concession. The theater is gorgeous, with 200 seats encircling the stage complete with Rolling Stones-style walkway. Oh yeah, baby! And of course in the same building there’s the Bella Union Bar for drinks before and after the show.

Tickets are already selling fast, so book today through Melbourne Fringe (03 9660 9666), or online at http://www.melbournefringe.com.au/season/2008/show/174

Thanks for reading, and I hope to catch you all during Fringe.

Free SMS service notifications using Google Calendar

Today I had a small revelation.

I was wracking my brains trying to figure out the SMS messaging provider to use to send myself service outage notifications for my clients’ web sites. Given that I have just a handful of clients so far, it makes no sense to use a provider that requires a minimum monthly or yearly spend.

Ideally of course, I’d like to spend nothing at all, and in exasperation I finally threw my hands in the air (they’re detachable) and whined: “Google sends SMS’s for free – why is it so hard for everyone else?”

(answer: not everyone has billions of dollars)

And then came the revelation: Why not create a command-line tool that uses Google’s Calendar API to create events 6 minutes in the future that have an SMS notification set for 5 minutes prior to launch? That way, within a minute you get a notification sent to your phone for free within 1 minute. Sweet!

So, here’s the code (it’s in Java… sorry)

/**
* Simple command-line notification command that uses Google Calendar ATOM API to create
* a single event 6 minutes in the future with a 5 minute SMS reminder
*
* @author Daniel Walmsley
*
*/

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.List;

import com.google.gdata.client.calendar.CalendarService;
import com.google.gdata.data.DateTime;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.calendar.CalendarEntry;
import com.google.gdata.data.calendar.CalendarEventEntry;
import com.google.gdata.data.calendar.CalendarFeed;
import com.google.gdata.data.extensions.Reminder;
import com.google.gdata.data.extensions.When;
import com.google.gdata.data.extensions.Reminder.Method;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;

/**
* This is a test template
*/

public class GCalNotifier {

public static void main(String[] args) {

    /**
     * Command line args: 
     * 
     * username
     * password
     * calendar name (e.g. "Notifications")
     * TimeZone offset (in hours)
     * event start offset (in minutes)
     * event end offset (in minutes)
     * title
     * description
     */

    try {

        // Create a new Calendar service
        CalendarService myService = new CalendarService("GCal Event Notifier");
        myService.setUserCredentials(args[0], args[1]);

        String calendarName = args[2];
        Long tzOffset = new Double(Double.parseDouble(args[3])).longValue() * 60 * 60 * 1000;
        Long startOffset = new Integer(Integer.parseInt(args[4])).longValue() * 60 * 1000;
        Long endOffset = new Integer(Integer.parseInt(args[5])).longValue() * 60 * 1000;
        String title = args[6];
        String description = args[7];

        // Get a list of all entries
        URL metafeedUrl = new URL(
                "http://www.google.com/calendar/feeds/default/allcalendars/full");
        System.out.println("Getting Calendar entries...n");
        CalendarFeed resultFeed = myService.getFeed(metafeedUrl,
                CalendarFeed.class);
        List<calendarentry> entries = resultFeed.getEntries();
        for (int i = 0; i < entries.size(); i++) {
            CalendarEntry entry = entries.get(i);
            String currCalendarName = entry.getTitle().getPlainText();
            System.out.println("t" + currCalendarName);

            if (currCalendarName.equals(calendarName)) {
                sendDowntimeAlert(myService, entry,
                        title, description, startOffset, endOffset, tzOffset);
            }
        }
        System.out.println("nTotal Entries: " + entries.size());

    } catch (AuthenticationException e) {
        e.printStackTrace();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (ServiceException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private static void sendDowntimeAlert(CalendarService myService,
        CalendarEntry entry, String title, String description, Long startOffset, Long endOffset, Long tzOffset) throws IOException,
        ServiceException {

    String postUrlString = entry.getLink("alternate", "application/atom+xml").getHref();

    URL postUrl = new URL(postUrlString);//was: "http://www.google.com/calendar/feeds/jo@gmail.com/private/full"

    CalendarEventEntry myEntry = new CalendarEventEntry();

    myEntry.setTitle(new PlainTextConstruct(title));
    myEntry.setContent(new PlainTextConstruct(description));

    Date now = new Date();

    Date startDate = new Date(now.getTime()+startOffset);
    Date endDate = new Date(now.getTime()+endOffset);

    DateTime startTime = new DateTime(startDate.getTime()+tzOffset);

    DateTime endTime = new DateTime(endDate.getTime()+tzOffset);

    When eventTimes = new When();
    eventTimes.setStartTime(startTime);
    eventTimes.setEndTime(endTime);
    myEntry.addTime(eventTimes);

    // Send the request and receive the response:
    CalendarEventEntry insertedEntry = myService.insert(postUrl, myEntry);
    System.err.println("Got response for: "+insertedEntry.getTitle().getPlainText());
    for(When when : insertedEntry.getTimes()) {
        System.err.println("When: "+when.getStartTime()+" to "+when.getEndTime());
    }

    //5 minute reminder
    Reminder reminder = new Reminder();
    reminder.setMinutes(5);
    reminder.setMethod(Method.SMS);
    insertedEntry.getReminder().add(reminder);
    insertedEntry.update();
}

}

Don’t forget, you’ll need to download the Google Data APIs and put their JARs in your classpath before this will work!

Personally I use this with Nagios. I always use the same args for the calendar offsets, so I’ve encapsulated most of my settings (except title and body) in a script.

!/bin/sh

export SCRIPTDIR=/opt/calAlert
export USERNAME=username@gmail.com
export PW=mySecurePassword
export CAL=Notifications
export TZOFFSET=10
export STARTOFFSET=7
export ENDOFFSET=12
export TITLE=$1
export BODY=$2

export CURRDIR=pwd

export CLASSPATH=”${SCRIPTDIR}/calAlert.jar”

assumes GData libs are in “libs” subdirectory of SCRIPTDIR

for jarfile in $(ls “${SCRIPTDIR}/lib”)
do
CLASSPATH=”${CLASSPATH}:${SCRIPTDIR}/lib/${jarfile}”
echo lib/${jarfile}
done

echo “CLASSPATH=${CLASSPATH}”

export CLASSPATH

java GCalNotifier ${USERNAME} ${PW} ${CAL} ${TZOFFSET} ${STARTOFFSET} ${ENDOFFSET} “${TITLE}” “${BODY}”

ACN Video Phone part XCVIII: The ACN-enning!

This is the umpteenth in our ongoing saga of the ACN Video Phone. To bring any newcomers up to speed:

Most recently some readers began criticising my rhetorical style, claiming I’d been particularly unfair on one commenter and that this had discredited my arguments in their opinion.

That’s a shame, because I’m really quite obviously correct about ACN, even if I’m not correct about the motivations of certain commenters (and that point remains to be proven one way or the other).

(I would point out that if a commenter criticises me and also runs an ACN-based business, as the person in question does, I’m entitled to assume they’re biased)

So now! Another great and worthy comment criticising my overreaction to someone’s comment and failing to engage critically with my main point. I see a pattern forming.

Interesting that you would respond in that way to Ravi and have to agree with matsonian about the manner/tone in which you required acknowledgement of/for yourself in a prescribed manner and yet could not return the favour.

You, sir/ma’am, write like someone trying to sound smart! And failing!

At what point did I “require” anything from Ravi? And in a prescribed manner? Uh, nope.

Reeking with sarcasm and cynicism, why is it so hard to allow Ravi his freedom to be an entrepreneur (obviously) for his business?

I’m sorry, I didn’t realise that I was preventing Ravi from being an entrepreneur!

Well in that case: Ravi! You are freed! Quit your cage and fly, my pretty, and be an entrepreneur!

I was under the mistaken impression that I was telling him his ACN-based business generates little value for resellers or customers but rather plays on people’s desperation and nativete. My bad.

Whoops! There goes that sarcasm again.

Note that I don’t have a personal problem with Ravi, I just think he’s got a conflict of interest. I have a far bigger beef with ACN, though it’s still not something I ever think about unless someone comments on my site and I have to write another one of these articles.

And there is always a prescribed manner in which one does things in their work regardless of what type of work, employment, career that person has”… wouldnt you agree?

I have no idea what you’re asking. You are being way, way too general.

If you’re talking about moral principles then yes, absolutely I would agree. For example, I think that lying and/or misrepresenting the profits that can be made from a home-based business by a global megalith like ACN is morally wrong.

I think that business should grow and individuals in that business should become wealthy based on the direct generation of value for consumers, not by selling someone a dream that is extremely unlikely to come true.

Life is full of dialogue and prescribed ways so in all fairness – live and let live ..?

I am living and letting live. In what way am I not? By writing about someone’s comment on my site that I own? You realise I actually approved his comment to go live, don’t you?

It’s not like I’m following this guy around or anything. I haven’t even sent him an email! How is that not living and letting live?

You’re weird, man.