Code Snippets

How to implement download counter to GAE file uploader

This guide will help you add download counter to the Google App Engine file uploader. Refer to this blog post for a more detailed explanation.

First download the complete example source code from Github to follow along.

First thing we need to do is define our data model. I'm going to call my class a very imaginative name DownloadCounter and give it a few variables to store the data.

 class DownloadCounter(ndb.Model):

  """Data model for the download counter"""

  blobkey = ndb.StringProperty(indexed=True)

  count_downloaded = ndb.IntegerProperty(indexed=False)

  last_ip = ndb.StringProperty(indexed=False)

The variable 'blobkey' is the most important, notice that we're indexing it. This will be our key when searching the Datastore.

Next, in the upload handler we need to instantiate this class and save it to the Datastore.

counter = DownloadCounter(blobkey=str(blob_info.key()), count_downloaded=0, last_ip='n/a')

ckey = counter.put()

The next step is to add the count updating code.

entry = DownloadCounter.query( DownloadCounter.blobkey==str(blob_key) ).get()

if (entry != None):

  entry.count_downloaded += 1

  entry.last_ip = self.request.remote_addr

  key = entry.put()

else: # no entry for this file, create it

  counter = DownloadCounter(blobkey=str(blob_key), count_downloaded=1, last_ip=self.request.remote_addr)

  ckey = counter.put()

You will notice here that we don't rely on the DownloadCounter object already existing in the Datastore. If this request is executed for a file that doesn't have a counter it will be created with 'count_downloaded=1'. Also, just for fun, we store the IP of the last client that downloaded the file.

Finally, we want to display this information along with every file that's currently in our system.

for b in blobstore.BlobInfo.all():

  last_ip = 'n/a'

  counter = 0

  entry = DownloadCounter.query( DownloadCounter.blobkey==str(b.key()) ).get()

  if (entry != None):

    counter = entry.count_downloaded

    last_ip = entry.last_ip

  self.response.out.write('' + str(b.filename) + ' Downloaded: '+ str(counter) +' times. Last from IP: '+ last_ip)

Notice here that we query the Datastore's DownloadCounter objects by the blobkey which is the unique identifier then extract the individual fields and display them along with the link to the image.

The end result would look something like this (depending on your starting example script).

Of course if this was a real app you would add CSS and use proper GAE templating.

End result



Resource Tags: