Data backup in Google AppEngine
Today I'm just going to share a little bit of code to download content from the DataStore in Google AppEngine. A few days ago I was worried about not having a recent backup of my blog. So I decided to write some code to download all the blog content in a convenient ZIP file. Here it is:
class Backup(webapp.RequestHandler):
"""Handler to download a file with a backup of the site.
Beware of the maximum response size in AppEngine, which could
cause failures with big files.
"""
def get(self):
# Set up headers for the browser to correctly recognize the ZIP file.
self.response.headers['Content-Type'] ='application/zip'
self.response.headers['Content-Disposition'] = \
'attachment; filename=' + BACKUP_FILE_NAME
# Write ZIP file directly to output stream.
output = ZipFile(self.response.out, "w", ZIP_DEFLATED)
# Compress posts and emit them directly to HTTP response stream.
# Encode file_name as ASCII, which is what the zipfile library uses.
for post in app.get_all_posts_and_drafts():
file_name = BACKUP_POSTS_DIRECTORY + post.title + '.txt'
file_info = ZipInfo()
file_info.filename = file_name.encode('ascii', 'ignore')
file_info.date_time = (post.date.year,
post.date.month,
post.date.day,
post.date.hour,
post.date.minute,
post.date.second)
file_info.external_attr = 0644 << 16L # R/W permissions.
post_content = 'Title: ' + post.title + '\nDate: ' + str(post.date) \
+ '\nUrl: ' + post.desired_url + '\n\n' + post.content
output.writestr(file_info, post_content.encode('ascii', 'ignore'))
# Now add the images. Same as before, encode the file_name as ASCII.
for image in app.get_all_images():
file_name = BACKUP_IMAGES_DIRECTORY + image.name
file_info = ZipInfo()
file_info.filename = file_name.encode('ascii', 'ignore')
file_info.external_attr = 0644 << 16L # R/W permissions.
output.writestr(file_info, image.get_data())
output.close()
Written on September 15, 2012