#Author: Stoyan Shopov
#Company: LISAsoft
#Licence: LGPL

import sys
from xml.etree import ElementTree as ET
try:
    from osgeo import ogr
except:
    print 'Please donwload and install Gdal for python from: http://trac.osgeo.org/gdal/wiki/GdalOgrInPython'
    sys.exit(1)

#modify this to match your GeoServer data_dir
data_dir = r'C:\Program Files\GeoServer 1.6.4\data_dir'

infoxmltemplate='''<featureType datastore = "%s" >
  <name>%s</name>
  <SRS>%s</SRS>
  <SRSHandling>0</SRSHandling>
  <title>%s_Type</title>
  <abstract>Generated from %s</abstract>
  <wmspath>/</wmspath>
  <numDecimals value = "8" />
  <keywords>%s %s</keywords>
  <latLonBoundingBox dynamic = "false" miny = "%s" maxy = "%s" maxx = "%s" minx = "%s" />
  <nativeBBox dynamic = "false" miny = "%s" maxy = "%s" maxx = "%s" minx = "%s" />
  <styles default = "%s" />
  <cacheinfo enabled = "false" maxage = "" />
  <maxFeatures>0</maxFeatures>
</featureType>'''
#usage: infoxmltemplate%(featureid,name,srs,name,featureid,name,featureid,miny,maxy,maxx,minx,miny,maxy,maxx,minx,sld)

datastoretemplate='''
    <datastore enabled="true" id="%s" namespace="topp">
      <connectionParams>
        <parameter name="create spatial index" value="true" />
        <parameter name="namespace" value="topp" />
        <parameter name="url" value="file:%s" />
        <parameter name="charset" value="ISO-8859-1" />
      </connectionParams>
    </datastore>'''

def shp2geoserver(shp,featureid,sld,srs):
    '''this method takes a path to a shapefile (it should already be in the geoserver's data_dir);
    a featureid name; a style name (as per catalog.xml); an SRS;
    and creates the necessary entries in catalog.xml and the featureTypes directory.
    It allows you to automate the Welcome->Config->Data->DataStores->New steps, so you can do a batch import of shapefiles
    I suggest you stop geoserver before running this or restart it straight after.'''

    ds = ogr.Open(shp)
    layer=ds.GetLayer(0)
    minx, maxx, miny, maxy = layer.GetExtent() #(min Long, max Long, min Lat, max Lat) = ( minx maxx miny maxy)
    name=layer.GetName()

    #add the new shapefile as a datastore to catalog.xml
    tree=ET.parse(os.path.join(data_dir,'catalog.xml'))
    root=tree.find('//datastores')
    datastoreexists = False #first check if the entry already exists
    for el in root.getiterator('datastore'):
        if el.attrib['id'] == featureid:
            datastoreexists = True

    if datastoreexists:
        print "Datastore %s already exists in catalog.xml. Operation ignored"%name #TODO: provide an overwrite option
        return

    newdatastore=ET.fromstring(datastoretemplate%(featureid,shp[len(data_dir)+1:].replace('\\','/')))
    root.append(newdatastore)
    tree.write(os.path.join(data_dir,'catalog.xml'))

    #create info.xml under the featureTypes dir
    featuredir=os.path.join(data_dir,r'featureTypes\%s'%(featureid))
    if not os.path.exists(featuredir):
        os.mkdir(featuredir)
    file(os.path.join(featuredir,'info.xml'),'w').write(infoxmltemplate%(featureid,name,srs,name,featureid,name,featureid,miny,maxy,maxx,minx,miny,maxy,maxx,minx,sld))
    print '%s: added'%shp

if __name__ == '__main__':
    '''used http://arcmap2sld.geoinform.fh-mainz.de/ArcMap2SLDConverter_Eng.htm to get an SLD file from a .mxd
    Gdal for python came from: http://trac.osgeo.org/gdal/wiki/GdalOgrInPython'''

    shp2geoserver(r'C:\Program Files\GeoServer 1.6.4\data_dir\data\Topo_GA\250k\aeronautical.shp','ds_aero','aeronauticalsld',4283)
