#! /usr/bin/env python
#
# This script will manually load/configure a shapefile into GeoServer.
# Created by Mike Pumphrey, July 2008
# 
# Process:
# 	1) Copy shapefile files to ./data 
#	2) Copy SLD to ./styles
#	3) append data block to ./catalog.xml
#		3a) <datastore id ... > for SHP
#		3b) <style id ... > for SLD
#	4) create directory ./featureTypes/foo_foo
#	5) create ./featureTypes/foo_foo/info.xml
#	6) reload configuration

import sys    # system stuff
import os     # for command lines
import shutil # for copying 

print "\nBatch shapefile installer.  (Mess made by Mike Pumphrey.)\n"

# Wrong arguments displays this
def usage():
	print ""
	print "Usage:"
	print "    script.py datadir shapefile style namespace srs"
	print "    (namespace and srs are not checked for existence/accuracy!)"
	sys.exit()

# Is this correct? [Y/n]
def isthiscorrect():
	wait=0
	while wait==0:
		check = raw_input("Is this correct? [Y/n]:")
		if check=="" or check.lower()=="y" or check.lower()=="yes":
			print "ok!"
			wait = 1
		elif check.lower()=="n" or check.lower()=="no":
			print "ne'er ye mind!"
			sys.exit()
	return

# need the proper amount of arguments!	
if len(sys.argv) < 6:
	print "Not enough arguments! (Found "+str(len(sys.argv))+")"
	usage()
if len(sys.argv) > 6:
	print "Too many arguments! (Found "+str(len(sys.argv))+")"
	usage()

datadir = sys.argv[1]

if not os.path.isdir(datadir)==True:
	print "Data directory "+datadir+" doesn't exist!"
	usage()

# Chomp datadir slash
if datadir[:-1]=="\\" or datadir[:-1]=="/":
	datadir = datadir[:1]

	
	
shapefile = sys.argv[2]

# Check for existence
if not os.path.isfile(shapefile):
	print "Shapefile doesn't exist!  (Check path)"
	usage()

# Split path/file
shapefilepath = os.path.dirname(shapefile)
shapefilename = os.path.basename(shapefile)


# Remove the extension
if shapefilename[-4:].lower()==".shp":
	shapefilebase = shapefilename[:-4]
else:
	print "Are you sure that's a shapefile? (expected .shp extension)"
	usage()

	
	
style = sys.argv[3]
# Remove the extension if there
if style[-4:].lower()==".sld":
	stylebase = style[:-4]
else:
	print "Are you sure that's an SLD file?  (expected.sld)"
	usage()

stylepath=os.path.join(datadir,"styles")

# Check for style existence
if not os.path.isfile(os.path.join(stylepath,style))==True:
	print "Style "+style+" cannot be found in "+stylepath+"!"
	usage()


# We're just going to assume that the namespace exists	
namespace = sys.argv[4]



# srs (strip the EPSG:)
srs = sys.argv[5]
if srs[:5].lower()=="epsg:":
	srs = srs[5:]

# 	1) Copy shapefile files to ./data
shapefilelist = []
print "The following files will be added to / clobbered in GeoServer from:"
print shapefilepath

listdir = os.listdir(shapefilepath)
for foo in listdir:
	if shapefilebase in foo:
		shapefilelist.append(foo) 
for foo in shapefilelist:
	print foo

isthiscorrect()
print "Copying..."
# Copy already!
for foo in shapefilelist:
	# print "Copying " + foo
	source = os.path.join(shapefilepath,foo)
	dest = os.path.join(datadir,"data",namespace,foo)
	shutil.copyfile(source,dest)


#	2) Copy SLD to ./styles
#           Actually, this version of the program assumes SLDs are already loaded.  Sorry...

#	3) append data block to ./catalog.xml
#		3a) <datastore id ... > for SHP

# build the catalog string
datastoreid = '''    <datastore id = "'''+shapefilebase+'''" enabled = "true" namespace = "'''+namespace+'''" >
      <connectionParams >
        <parameter name = "charset" value = "ISO-8859-1" />
        <parameter name = "url" value = "file:data/'''+namespace+'''/'''+shapefilename+'''" />
        <parameter name = "namespace" value = "'''+namespace+'''" />
      </connectionParams>
    </datastore>'''

# Thanks jhammel!!!!!!!

# backup first
shutil.copyfile(os.path.join(datadir,"catalog.xml"),os.path.join(datadir,"catalog.xml.bak"))

# pick file and read into memory!  eek!
f = file(os.path.join(datadir,"catalog.xml"))
# print "f = " +str(f)
lines = f.readlines()

# vars
schnitt = "</datastores>"
location = None

# find the location where we make the cut
for index,line in enumerate(lines):
    if line.strip()==schnitt:         # whitespace
        location = index
        break
		
f.close()

assert location is not None

# new file for writing
f = file(os.path.join(datadir,"catalog.xml"), "w")
lines = [line.rstrip() for line in lines] # strip from right only

# everything before
for line in lines[:location]:       # slice non-inclusive
    print >> f,line

# the new stuff inserted
print >> f, datastoreid

# everything after
for line in lines[location:]:      # inclusive on left only
    print >> f, line

f.close()

#	3) append data block to ./catalog.xml
#		3b) <style id ... > for SLD
#       Again, this version won't care about uploading styles.  Next time, Gadget...

#styleid = '    <style id = "'+stylebase+'" filename = "'+stylebase+'.sld" />'
#print " "
#print styleid


#	4) create directory ./featureTypes/foo_foo

shapefiledir = shapefilebase+"_"+shapefilebase
if not os.path.exists(os.path.join(datadir,"featureTypes",shapefiledir)):
	os.mkdir(os.path.join(datadir,"featureTypes",shapefiledir))


#	5) create ./featureTypes/foo_foo/info.xml

infoxml = '''<featureType datastore = "'''+shapefilebase+'''" >
   <name>'''+shapefilebase+'''</name>
   <!--
     native wich EPGS code for the FeatureTypeInfoDTO
   -->
   <SRS>'''+srs+'''</SRS>
   <SRSHandling>0</SRSHandling>
   <title>'''+shapefilebase+'''</title>
   <abstract>Generated from '''+shapefilename+'''</abstract>
   <wmspath>/</wmspath>
   <numDecimals value = "8" />
   <keywords>'''+shapefilebase+'''</keywords>
   <latLonBoundingBox dynamic = "false" maxx = "-82.03700549564535" maxy = "29.947154750192915" minx = "-82.66556904877645" miny = "29.415044628355446" />
   <nativeBBox dynamic = "false" maxx = "2752668.0141602154" maxy = "352879.47662596434" minx = "2549451.9940357623" miny = "155642.5688518099" />
   <!--
     the default style this FeatureTypeInfoDTO can be represented by.
     at least must contain the "default" attribute
   -->
   <styles default = "'''+stylebase+'''" />
   <cacheinfo enabled = "false" maxage = "" />
   <maxFeatures>0</maxFeatures>
</featureType>'''
 

f = file(os.path.join(datadir,"featureTypes",shapefiledir,"info.xml"), "w")
print >> f, infoxml
f.close()


#	6) reload configuration

print "Success!  "+shapefilebase+" has been successfully added to GeoServer's configuration.  Don't forget to reload!"
sys.exit()




