Event Management Automatisation using Apps Script

Last year the network I help to run, KIN, decided to start using Google Sites for their shared online space called MemberSpace. This ‘MemberSpace’ is used as a repository for shared documents and information about various KIN events. I soon realised that using Google Apps Script would significantly enhance the event management process.

The network facilitators organise about 30-40 events a year. For each event we need to :

  • Create an Events page in the MemberSpace Google Site (in a standardised format)
  • Create a Calender Event in the Network Events Calendar maintained by facilitators
  • Announce the event on the MemberSpace news (announcements) page
  • Allow delegate self-registration
  • Send attendees a customized email confirmation when they register
  • Send joining instructions emails to all attendees immediately prior to the event

By using Google Apps Script, we have been able to automate all of the above tasks and make event management a lot simpler.

The Solution

To accomplish this automation, we have created an event management spreadsheet template with an accompanying form and script. Whenever an event is organised, the event facilitator copies the event management template and fills in standard data about the event in one of the sheets.

Then all the facilitator has to do is select the appropriate menu items to accomplish the tasks listed above. (This spreadsheet is only seen by the Facilitators. The event attendees only see the event registration form.)

So what’s in the script behind this?

Before I started this project, I had never used Javascript. I used various tutorials on Apps Script documentation site to learn about Apps Script and discovered that a good starting point was the Simple Mail Merge Google Apps Script tutorial. The workflow of managing an event was relatively simple but required integration with various services such as Mail, Calendar, Contacts, Forms and Sites. Below is a description of how we used Apps Script to automate these tasks.

1. Event Registration Email

Whenever an attendee registers for an event, we need to send a customised confirmation email. This script is based on the Simple Mail Merge Google Apps Script tutorial code and we use an onFormSubmit trigger to automatically run the script to email registration confirmation to delegates when they submit a registration form. Mail Services in Apps Script are used to send these emails.

2. Event Page in Sites

The ‘Create Event Page’ script is invoked by the facilitator to create an event page (using Apps Script Sites Services) in the MemberSpace using one of three page templates depending on the event type. Should any event details change, this script can be run again to delete the original page and create a new one with the amended details.

3. Calendar entry in Events Calendar

Once the event page has been created, the organiser creates an entry in the calendar by running the ‘Create Calendar Entry’ script which generates a calendar entry containing a link to the previously created event page in the MemberSpace. This script uses Apps Script Calendar Services.

4. Email confirmation / joining instructions

A week or so before the event takes place, joining instructions are sent to delegates using a menu option from the original spreadsheet. This runs a slightly modified version of the email script used in step 1.

5. Event Announcement in Sites

Finally, the organiser can ‘announce’ the event by running the ‘Announce Event’ script which places an announcement in the MemberSpace News page. (Actually, there are three ‘Special Interest Group’ News pages and one ‘General’ News page which are merged – by a time trigger driven script – into a single announcements stream that can subscribed to using a Site Services script the basis of which can be found here.)

Performing the above tasks manually may seem simple or trivial but it can be time consuming and error prone. By using Apps Script, we have implemented event management functionality that allows us to manage events in a standardised way.

Google Latitude: Check in, gain status, and unlock offers at more places

Last month, we rolled out Google Latitude check-in offers for 60 places around Austin. Today, we’re happy to announce that we’ve teamed up with some great partners to let you unlock check-in offers at thousands of places across the U.S. using Latitude for Android and iPhone. You can learn more at google.com/latitude/checkin.

Checking in lets you share the places that you visit and add context to your Latitude location for friends and family. At the same time, you can keep a history of where you’ve been while gaining status at the places you visit the most. When you gain status at places, they can now reward your loyalty with check-in offers. From discounts to a free snack, check-in offers let places give you an extra reason to keep coming back. Here’s how to get started:

  1. Check in. Check in using Latitude to share places with friends when you’re there.
  2. Gain status. Keep checking in every time you visit your favorite places to gain status there. You can tap your current status level to see your progress towards the next status level.
  3. Unlock offers. Places can make check-in offers available to you at each of their 3 status levels. When you gain higher status, you’ll unlock any available check-in offers.
From a Place page, check in, see your current status, and find check-in offers (left); tap your current status to see your progress to the next level (right).

You’ll be able to see both available and locked offers at places. To redeem an available check-in offer, just select it from the Place page, tap Redeem, and show the full offer on your phone.

See available and locked offers (left); tap available ones to redeem them (right).

By default, you can become a Regular, VIP, or Guru at places, but we’re also letting partners create their own status levels for you to achieve (coming soon on iPhone). For example, you can become a Champion of Taste at Quiznos or an AE Gold Shopper at American Eagle Outfitters, unlocking their check-in offers at the same time. Take a peek at some of our partners and their check-in offers below or see all of them at google.com/latitude/checkin.

  • American Eagle Outfitters: Up to 20% off your total purchase
  • Quiznos: Free sub when you buy a sub of equal or greater value
  • Arby’s: Free regular roast beef sandwich with purchase of a 22 oz. drink
  • RadioShack: Up to 20% off qualifying, in-store purchases
  • Finish Line: Save $10 on purchases over $50
  • Macy’s (Coming soon)

To start unlocking offers with Latitude, update to the latest version of Google Maps for Android (Latitude is a feature of Maps; requires Android 1.6+) or the Latitude app for iPhone. So start checking in at places when you’re there, and you might just unlock some great offers along the way.

Memory Analysis for Android Applications

The Dalvik runtime may be garbage-collected, but that doesn’t mean you can ignore memory management. You should be especially mindful of memory usage on mobile devices, where memory is more constrained. In this article, we’re going to take a look at some of the memory profiling tools in the Android SDK that can help you trim your application’s memory usage.

Some memory usage problems are obvious. For example, if your app leaks memory every time the user touches the screen, it will probably trigger an OutOfMemoryError eventually and crash your app. Other problems are more subtle, and may just degrade the performance of both your app (as garbage collections are more frequent and take longer) and the entire system.

Tools of the trade

The Android SDK provides two main ways of profiling the memory usage of an app: the Allocation Tracker tab in DDMS, and heap dumps. The Allocation Tracker is useful when you want to get a sense of what kinds of allocation are happening over a given time period, but it doesn’t give you any information about the overall state of your application’s heap. For more information about the Allocation Tracker, see the article on Tracking Memory Allocations. The rest of this article will focus on heap dumps, which are a more powerful memory analysis tool.

A heap dump is a snapshot of an application’s heap, which is stored in a binary format called HPROF. Dalvik uses a format that is similar, but not identical, to the HPROF tool in Java. There are a few ways to generate a heap dump of a running Android app. One way is to use the Dump HPROF file button in DDMS. If you need to be more precise about when the dump is created, you can also create a heap dump programmatically by using theandroid.os.Debug.dumpHprofData() function.

To analyze a heap dump, you can use a standard tool like jhat or the Eclipse Memory Analyzer (MAT). However, first you’ll need to convert the .hprof file from the Dalvik format to the J2SE HPROF format. You can do this using the hprof-conv tool provided in the Android SDK. For example:

hprof-conv dump.hprof converted-dump.hprof

Example: Debugging a memory leak

In the Dalvik runtime, the programmer doesn’t explicitly allocate and free memory, so you can’t really leak memory like you can in languages like C and C++. A “memory leak” in your code is when you keep a reference to an object that is no longer needed. Sometimes a single reference can prevent a large set of objects from being garbage collected.

Let’s walk through an example using the Honeycomb Gallery sample app from the Android SDK. It’s a simple photo gallery application that demonstrates how to use some of the new Honeycomb APIs. (To build and download the sample code, see the instructions.) We’re going to deliberately add a memory leak to this app in order to demonstrate how it could be debugged.

Imagine that we want to modify this app to pull images from the network. In order to make it more responsive, we might decide to implement a cache which holds recently-viewed images. We can do that by making a few small changes to ContentFragment.java. At the top of the class, let’s add a new static variable:

private static HashMap<String,Bitmap> sBitmapCache = new HashMap<String,Bitmap>();

This is where we’ll cache the Bitmaps that we load. Now we can change the updateContentAndRecycleBitmap() method to check the cache before loading, and to add Bitmaps to the cache after they’re loaded.

void updateContentAndRecycleBitmap(int category, int position) {
    if (mCurrentActionMode != null) {
        mCurrentActionMode.finish();
    }
 
    // Get the bitmap that needs to be drawn and update the ImageView.
 
    // Check if the Bitmap is already in the cache
    String bitmapId = "" + category + "." + position;
    mBitmap = sBitmapCache.get(bitmapId);
 
    if (mBitmap == null) {
        // It's not in the cache, so load the Bitmap and add it to the cache.
        // DANGER! We add items to this cache without ever removing any.
        mBitmap = Directory.getCategory(category).getEntry(position)
                .getBitmap(getResources());
        sBitmapCache.put(bitmapId, mBitmap);
    }
    ((ImageView) getView().findViewById(R.id.image)).setImageBitmap(mBitmap);
}

I’ve deliberately introduced a memory leak here: we add Bitmaps to the cache without ever removing them. In a real app, we’d probably want to limit the size of the cache in some way.

Examining heap usage in DDMS

The Dalvik Debug Monitor Server (DDMS) is one of the primary Android debugging tools. DDMS is part of the ADT Eclipse plug-in, and a standalone version can also be found in the tools/ directory of the Android SDK. For more information on DDMS, see Using DDMS.

Let’s use DDMS to examine the heap usage of this app. You can start up DDMS in one of two ways:

  • from Eclipse: click Window > Open Perspective > Other… > DDMS
  • or from the command line: run ddms (or ./ddms on Mac/Linux) in the tools/ directory

Select the process com.example.android.hcgallery in the left pane, and then click the Show heap updates button in the toolbar. Then, switch to theVM Heap tab in DDMS. It shows some basic stats about our heap memory usage, updated after every GC. To see the first update, click the Cause GCbutton.

We can see that our live set (the Allocated column) is a little over 8MB. Now flip through the photos, and watch that number go up. Since there are only 13 photos in this app, the amount of memory we leak is bounded. In some ways, this is the worst kind of leak to have, because we never get anOutOfMemoryError indicating that we are leaking.

Creating a heap dump

Let’s use a heap dump to track down the problem. Click the Dump HPROF file button in the DDMS toolbar, choose where you want to save the file, and then run hprof-conv on it. In this example, I’ll be using the standalone version of MAT (version 1.0.1), available from the MAT download site.

If you’re running ADT (which includes a plug-in version of DDMS) and have MAT installed in Eclipse as well, clicking the “dump HPROF” button will automatically do the conversion (using hprof-conv) and open the converted hprof file into Eclipse (which will be opened by MAT).

Analyzing heap dumps using MAT

Start up MAT and load the converted HPROF file we just created. MAT is a powerful tool, and it’s beyond the scope of this article to explain all it’s features, so I’m just going to show you one way you can use it to detect a leak: the Histogram view. The Histogram view shows a list of classes sortable by the number of instances, the shallow heap (total amount of memory used by all instances), or the retained heap (total amount of memory kept alive by all instances, including other objects that they have references to).

If we sort by shallow heap, we can see that instances of byte[] are at the top. As of Android 3.0 (Honeycomb), the pixel data for Bitmap objects is stored in byte arrays (previously it was not stored in the Dalvik heap), and based on the size of these objects, it’s a safe bet that they are the backing memory for our leaked bitmaps.

Right-click on the byte[] class and select List Objects > with incoming references. This produces a list of all byte arrays in the heap, which we can sort based on Shallow Heap usage.

Pick one of the big objects, and drill down on it. This will show you the path from the root set to the object — the chain of references that keeps this object alive. Lo and behold, there’s our bitmap cache!

MAT can’t tell us for sure that this is a leak, because it doesn’t know whether these objects are needed or not — only the programmer can do that. In this case, the cache is using a large amount of memory relative to the rest of the application, so we might consider limiting the size of the cache.

Comparing heap dumps with MAT

When debugging memory leaks, sometimes it’s useful to compare the heap state at two different points in time. To do this, you’ll need to create two separate HPROF files (don’t forget to convert them using hprof-conv).

Here’s how you can compare two heap dumps in MAT (it’s a little complicated):

  1. Open the first HPROF file (using File > Open Heap Dump).
  2. Open the Histogram view.
  3. In the Navigation History view (use Window > Navigation History if it’s not visible), right click on histogram and select Add to Compare Basket.
  4. Open the second HPROF file and repeat steps 2 and 3.
  5. Switch to the Compare Basket view, and click Compare the Results (the red “!” icon in the top right corner of the view).

SketchUp Pro 8: Introducing the Advanced Camera Tools

From the looks of it, we’re taking Hollywood by storm.

It seems that every time I watch a movie’s special features, up pops SketchUp: How’d they figure out the Penrose stairs in Inception? What did a vehicle designer for Avatar use to invent the bad guys’ robot suits? What tool did the production designer for 300 and Good Night, and Good Luck use? The set design for The Social Network? Futuristic environments for Tron: Legacy? The sheer number of films and TV shows that SketchUp’s been a part of is jaw-dropping—and we couldn’t be happier about it.

Since the entertainment industry’s been so good to us, we thought we’d return the favor. The old Film & Stage plugin we built in 2005 has been languishing in quasi-supported limbo for years. We dug it out of the shed, took it all apart, fixed the broken stuff, then… strapped a rocket to its butt. If fact, we made it so much better that we had to give it a new name.

The Advanced Camera Tools plugin lets you work with real-world cameras in your SketchUp Pro 8 models. Cameras you create with the ACTs provide precise controls for settings like Focal Length, Aspect Ratio and Image Width, which allows you to accurately preview real camera shots right inside SketchUp.

We put together a little video that tells the story succinctly:

In words and pictures, here’s some of what you can do with the Advanced Camera Tools:

Place cameras in your model and look through them to preview your shots.
Choose from dozens of pre-configured camera types, or create your own.
Position and aim your ACT cameras using familiar moves like Pan, Tilt, Roll, Dolly, Truck and Pedestal.

Set the Focal Length of any camera to simulate a large number of physical lenses.
Look through your ACT cameras to preview Aspect Ratio and Safe Zones for the shots you’re planning.
Toggle on and off all of your ACT cameras’ frustums to clearly see what is—and isn’t— visible in your shots.

The Advanced Camera Tools work on both Windows and Mac computers running SketchUp Pro 8. The plugin itself is a free download; you can get it here: Windows | Mac OS X

This Getting Started Guide is a good place to look for answers to your questions. To join a discussion, check out this thread on our forums.

Six years ago, we also released a big collection of components that relate specifically to film and tv production. If you need a dolly or a jib or a light stand or a light or a scissor lift or any other piece of movie set apparatus, this collection of collections on the 3D Warehouse is a great place to start looking.

One more thing: The lion’s share of credit for getting these tools out the door goes to Brian Brown. He worked on them in his 20% time—his day job is leading the engineering effort for Building Maker and the 3D Warehouse. Small tokens of appreciation (RED ONE HD cameras, etc.) should be mailed directly to him.