Skip to content

Commit

Permalink
Added tilecache server, not yet fully functional
Browse files Browse the repository at this point in the history
  • Loading branch information
Deepwinter committed Mar 15, 2012
1 parent 335d17f commit cc503b0
Show file tree
Hide file tree
Showing 74 changed files with 6,745 additions and 0 deletions.
21 changes: 21 additions & 0 deletions server.js
Expand Up @@ -2,7 +2,20 @@ var http = require('http');
var httpProxy = require('http-proxy');
var fs = require('fs');
var path = require('path');
var cgi = require('cgi');

var tilecache = http.createServer(
cgi('tilecache-2.11/tilecache.cgi')
).listen(6078);


var tileProxy = new httpProxy.HttpProxy({
target: {
host: 'localhost',
port: 6078
}
});



var proxy = new httpProxy.HttpProxy({
Expand All @@ -23,6 +36,14 @@ http.createServer(function (request, response) {
proxy.proxyRequest(request, response);
return;
}


if(request.url.indexOf('/tilecache-2.11/tilecache.cgi') == 0){
request.url = request.url.replace('tilecache-2.11/','');
tileProxy.proxyRequest(request, response);
return;
}


var filePath = '.' + request.url;
if (filePath == './')
Expand Down
48 changes: 48 additions & 0 deletions tilecache-2.11/TileCache/Cache.py
@@ -0,0 +1,48 @@
# BSD Licensed, Copyright (c) 2006-2010 TileCache Contributors
import os, sys, time
from warnings import warn

class Cache (object):
def __init__ (self, timeout = 30.0, stale_interval = 300.0, readonly = False, expire = False, sendfile = False, **kwargs):
self.stale = float(stale_interval)
self.timeout = float(timeout)
self.readonly = readonly
self.expire = expire
self.sendfile = sendfile and sendfile.lower() in ["yes", "y", "t", "true"]
if expire != False:
self.expire = long(expire)

def lock (self, tile, blocking = True):
start_time = time.time()
result = self.attemptLock(tile)
if result:
return True
elif not blocking:
return False
while result is not True:
if time.time() - start_time > self.timeout:
raise Exception("You appear to have a stuck lock. You may wish to remove the lock named:\n%s" % self.getLockName(tile))
time.sleep(0.25)
result = self.attemptLock(tile)
return True

def getLockName (self, tile):
return self.getKey(tile) + ".lck"

def getKey (self, tile):
raise NotImplementedError()

def attemptLock (self, tile):
raise NotImplementedError()

def unlock (self, tile):
raise NotImplementedError()

def get (self, tile):
raise NotImplementedError()

def set (self, tile, data):
raise NotImplementedError()

def delete(self, tile):
raise NotImplementedError()
Binary file added tilecache-2.11/TileCache/Cache.pyc
Binary file not shown.
181 changes: 181 additions & 0 deletions tilecache-2.11/TileCache/Caches/AWSS3.py
@@ -0,0 +1,181 @@
# BSD Licensed, Copyright (c) 2006-2010 TileCache Contributors
from TileCache.Cache import Cache
import time

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)

def getBotoKey(self, key):
boto_key = self.s3.key.Key(self.bucket)
boto_key.key = key
return boto_key

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

def get(self, tile):
key = self.getKey(tile)
tile.data = self.getObject(key)
return tile.data

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

def set(self, tile, data):
if self.readonly: return data
key = self.getKey(tile)
self.setObject(key, data)
return data

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()

def delete(self, tile):
key = self.getKey(tile)
self.deleteObject(key)

def deleteObject(self, key):
if self.module == "amazon":
self.cache.delete(self.bucket_name, key)
else:
self.getBotoKey(key).delete()

def getLockName (self, tile):
return "lock-%s" % self.getKey(tile)

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

def unlock (self, tile):
self.deleteObject( self.getLockName(tile) )

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()

125 changes: 125 additions & 0 deletions tilecache-2.11/TileCache/Caches/Disk.py
@@ -0,0 +1,125 @@
# BSD Licensed, Copyright (c) 2006-2010 TileCache Contributors

from TileCache.Cache import Cache
import sys, os, time, warnings

class Disk (Cache):
def __init__ (self, base = None, umask = '002', **kwargs):
Cache.__init__(self, **kwargs)
self.basedir = base
self.umask = int(umask, 0)
if sys.platform.startswith("java"):
from java.io import File
self.file_module = File
self.platform = "jython"
else:
self.platform = "cpython"

if not self.access(base, 'read'):
self.makedirs(base)

def makedirs(self, path, hide_dir_exists=True):
if hasattr(os, "umask"):
old_umask = os.umask(self.umask)
try:
os.makedirs(path)
except OSError, E:
# os.makedirs can suffer a race condition because it doesn't check
# that the directory doesn't exist at each step, nor does it
# catch errors. This lets 'directory exists' errors pass through,
# since they mean that as far as we're concerned, os.makedirs
# has 'worked'
if E.errno != 17 or not hide_dir_exists:
raise E
if hasattr(os, "umask"):
os.umask(old_umask)

def access(self, path, type='read'):
if self.platform == "jython":
if type == "read":
return self.file_module(path).canRead()
else:
return self.file_module(path).canWrite()
else:
if type =="read":
return os.access(path, os.R_OK)
else:
return os.access(path, os.W_OK)

def getKey (self, tile):
components = ( self.basedir,
tile.layer.name,
"%02d" % tile.z,
"%03d" % int(tile.x / 1000000),
"%03d" % (int(tile.x / 1000) % 1000),
"%03d" % (int(tile.x) % 1000),
"%03d" % int(tile.y / 1000000),
"%03d" % (int(tile.y / 1000) % 1000),
"%03d.%s" % (int(tile.y) % 1000, tile.layer.extension)
)
filename = os.path.join( *components )
return filename

def get (self, tile):
filename = self.getKey(tile)
if self.access(filename, 'read'):
if self.sendfile:
return filename
else:
tile.data = file(filename, "rb").read()
return tile.data
else:
return None

def set (self, tile, data):
if self.readonly: return data
filename = self.getKey(tile)
dirname = os.path.dirname(filename)
if not self.access(dirname, 'write'):
self.makedirs(dirname)
tmpfile = filename + ".%d.tmp" % os.getpid()
if hasattr(os, "umask"):
old_umask = os.umask(self.umask)
output = file(tmpfile, "wb")
output.write(data)
output.close()
if hasattr(os, "umask"):
os.umask( old_umask );
try:
os.rename(tmpfile, filename)
except OSError:
os.unlink(filename)
os.rename(tmpfile, filename)
tile.data = data
return data

def delete (self, tile):
filename = self.getKey(tile)
if self.access(filename, 'read'):
os.unlink(filename)

def attemptLock (self, tile):
name = self.getLockName(tile)
try:
self.makedirs(name, hide_dir_exists=False)
return True
except OSError:
pass
try:
st = os.stat(name)
if st.st_ctime + self.stale < time.time():
warnings.warn("removing stale lock %s" % name)
# remove stale lock
self.unlock(tile)
self.makedirs(name)
return True
except OSError:
pass
return False

def unlock (self, tile):
name = self.getLockName(tile)
try:
os.rmdir(name)
except OSError, E:
print >>sys.stderr, "unlock %s failed: %s" % (name, str(E))
Binary file added tilecache-2.11/TileCache/Caches/Disk.pyc
Binary file not shown.

0 comments on commit cc503b0

Please sign in to comment.