Source code for TileCache.Caches.AWSS3

# BSD Licensed, Copyright (c) 2006-2010 TileCache Contributors
from TileCache.Cache import Cache
import time

[docs]class AWSS3(Cache): import_error = "Problem importing S3 support library. You must have either boto or the Amazon S3 library.\nErrors:\n * %s" def __init__ (self, access_key, secret_access_key, use_tms_paths = "False", **kwargs): self.module = None try: import boto.s3 self.s3 = boto.s3 self.module = "boto" except ImportError, E: exceptions = [str(E)] try: import S3 self.s3 = S3 self.module = "amazon" except Exception, E: exceptions.append(str(E)) raise Exception(self.import_error % ('\n * '.join(exceptions))) Cache.__init__(self, **kwargs) self.bucket_name = "%s-tilecache" % access_key.lower() if use_tms_paths.lower() in ("true", "yes", "1"): use_tms_paths = True elif use_tms_paths.lower() == "flipped": use_tms_paths = "google" self.use_tms_paths = use_tms_paths if self.module == "amazon": self.cache = self.s3.AWSAuthConnection(access_key, secret_access_key) self.cache.create_bucket(self.bucket_name) else: self.cache = self.s3.connection.S3Connection(access_key, secret_access_key) self.bucket = self.cache.create_bucket(self.bucket_name)
[docs] def getBotoKey(self, key): boto_key = self.s3.key.Key(self.bucket) boto_key.key = key return boto_key
[docs] def getKey(self, tile): if self.use_tms_paths == True or self.use_tms_paths == "flipped": grid = tile.layer.grid(tile.z) y = tile.y if self.use_tms_paths == "flipped": y = int(grid[1] - 1 - tile.y) version = "1.0.0" path = "/".join(map(str, [version, tile.layer.name, tile.z, tile.x, y])) path = ".".join(map(str, [path, tile.layer.extension])) else: path = "-".join(map(str, [tile.layer.name, tile.z , tile.x, tile.y])) return path
[docs] def get(self, tile): key = self.getKey(tile) tile.data = self.getObject(key) return tile.data
[docs] def getObject(self, key): data = None if self.module == "amazon": response = self.cache.get(self.bucket_name, key) if not response.object.data.startswith("<?xml"): data = response.object.data else: try: data = self.getBotoKey(key).get_contents_as_string() except: pass self.bucket.connection.connection.close() return data
[docs] def set(self, tile, data): if self.readonly: return data key = self.getKey(tile) self.setObject(key, data) return data
[docs] def setObject(self, key, data): if self.module == "amazon": self.cache.put(self.bucket_name, key, self.s3.S3Object(data)) else: self.getBotoKey(key).set_contents_from_string(data) self.bucket.connection.connection.close()
[docs] def delete(self, tile): key = self.getKey(tile) self.deleteObject(key)
[docs] def deleteObject(self, key): if self.module == "amazon": self.cache.delete(self.bucket_name, key) else: self.getBotoKey(key).delete()
[docs] def getLockName (self, tile): return "lock-%s" % self.getKey(tile)
[docs] def attemptLock (self, tile): data = self.getObject(self.getLockName(tile)) if not data: self.setObject(self.getLockName(tile), str(time.time() + self.timeout)) return True
[docs] def unlock (self, tile): self.deleteObject( self.getLockName(tile) )
[docs] def keys (self, options = {}): if self.module == "amazon": return map(lambda x: x.key, self.cache.list_bucket(self.bucket_name, options).entries) else: prefix = "" if options.has_key('prefix'): prefix = options['prefix'] response = self.bucket.list(prefix=prefix) keys = [] for key in response: keys.append(key.key) return keys
if __name__ == "__main__": import sys from optparse import OptionParser parser = OptionParser(usage="""%prog [options] action action is one of: list_locks count_tiles show_tiles delete <object_key> or <list>,<of>,<keys> delete_tiles""") parser.add_option('-z', dest='zoom', help='zoom level for count_tiles (requires layer name)') parser.add_option('-l', dest='layer', help='layer name for count_tiles') parser.add_option('-k', dest='key', help='access key for S3') parser.add_option('-s', dest='secret', help='secret access key for S3') (options, args) = parser.parse_args() if not options.key or not options.secret or not args: parser.print_help() sys.exit() def create_prefix(options): prefix = "" if options.layer: prefix = "%s-" % options.layer if options.zoom: prefix = "%s%s-" % (prefix, options.zoom) return prefix # Debug mode. a = AWSS3(options.key, options.secret) if args[0] == "list_locks": print ','.join(a.keys({'prefix':'lock-'})) elif args[0] == "list_keys": print ','.join(a.keys()) elif args[0] == "count_tiles" or args[0] == "show_tiles": opts = { 'prefix': create_prefix(options) } if args[0] == "show_tiles": print ",".join(a.keys(opts)) else: print len(a.keys(opts)) elif args[0] == "delete": for key in args[1].split(","): a.deleteObject(key) elif args[0] == "delete_tiles": opts = { 'prefix': create_prefix(options) } keys = a.keys(opts) val = raw_input("Are you sure you want to delete %s tiles? (y/n) " % len(keys)) if val.lower() in ['y', 'yes']: for key in keys: a.deleteObject(key) else: parser.print_help()