Here is the program that I ended up writing. This actually edits the schemalock properties of all the services.
# For Http calls
import httplib, urllib, json
# For system tools
import sys, os, time, datetime, string
# For reading passwords without echoing
import getpass
# For sending email
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
# Local Variables
messages=""
errors = "N"
now = datetime.datetime.now()
logFile = r"c:\Central GIS\EditSchemaLocks" + string.replace(time.asctime(), ":", "_") + ".log"
output = open(logFile, "w")
# Defines the entry point into the script
def main(argv=None):
# Print some info
print
print "This script updates the lock schema property for every service"
print
# Open logfile
output.write(time.ctime() + ":\n" + "Starting Process..." + "\n\n")
# Ask for admin/publisher user name and password
username = raw_input("Enter user name: ")
password = getpass.getpass("Enter password: ")
# Ask for server name
serverName = raw_input("Enter Server name: ")
serverPort = 6080
# Get a token
output.write(time.ctime() + ":\n" + "Getting Token..." + "\n\n")
token = getToken(username, password, serverName, serverPort)
if token == "":
print "Could not generate a token with the username and password provided."
output.write(time.ctime() + ":\n" + "Could not generate a token with the username and password provided." + "\n\n")
error = "Y"
closeLogFile()
return
# Get a list of services
output.write(time.ctime() + ":\n" + "Get List of Services..." + "\n\n")
params = urllib.urlencode({'token': token, 'f': 'json'})
# The first list of services doesn't have a folder but does have a list of folder names
servicesObj = sendRequest(params, serverName, serverPort, "/arcgis/admin/services/")
if (servicesObj != ""):
folderDetails = servicesObj["foldersDetail"]
services = servicesObj["services"]
editService(params, serverName, serverPort, services, "", token)
# Now get list of services in each folder
for folder in folderDetails:
output.write(time.ctime() + ":\n" + "Get List of Services for folder " + folder["folderName"] + "\n\n")
servicesObj = sendRequest(params, serverName, serverPort, "/arcgis/admin/services/" + folder["folderName"])
if (servicesObj != ""):
services = servicesObj["services"]
editService(params, serverName, serverPort, services, folder["folderName"], token)
output.write(time.ctime() + ":\n" + "Process Complete." + "\n\n")
closeLogFile()
return
# A function to generate a token given username, password and the adminURL.
def getToken(username, password, serverName, serverPort):
# Token URL is typically http://server[:port]/arcgis/admin/generateToken
tokenURL = "/arcgis/admin/generateToken"
params = urllib.urlencode({'username': username, 'password': password, 'client': 'requestip', 'f': 'json'})
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
# Connect to URL and post parameters
httpConn = httplib.HTTPConnection(serverName, serverPort)
httpConn.request("POST", tokenURL, params, headers)
# Read response
response = httpConn.getresponse()
if (response.status != 200):
httpConn.close()
print "Error while fetching tokens from admin URL. Please check the URL and try again."
output.write(time.ctime() + ":\n" + "Error while fetching tokens from admin URL. Please check the URL and try again." + "\n\n")
error = "Y"
return
else:
data = response.read()
httpConn.close()
# Check that data returned is not an error object
if not assertJsonSuccess(data):
return
# Extract the token from it
token = json.loads(data)
return token['token']
# A function that checks that the input JSON object
# is not an error object.
def assertJsonSuccess(data):
obj = json.loads(data)
if 'status' in obj and obj['status'] == "error":
print "Error: JSON object returns an error. " + str(obj)
output.write(time.ctime() + ":\n" + "Error: JSON object returns an error. " + str(obj) + "\n\n")
error = "Y"
return False
else:
return True
# A function to send an HTTP Request
def sendRequest(params, serverName, serverPort, requestURL):
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
httpConn = httplib.HTTPConnection(serverName, serverPort)
httpConn.request("POST", requestURL, params, headers)
# Read response
response = httpConn.getresponse()
if (response.status != 200):
httpConn.close()
print "Could not read requestURL" + requestURL
output.write(time.ctime() + ":\n" + "Could not read requestURL" + requestURL + "\n\n")
error = "Y"
return ""
else:
data = response.read()
# Check that data returned is not an error object
if not assertJsonSuccess(data):
print "Error when reading data. " + str(data)
output.write(time.ctime() + ":\n" + "Error when reading data. " + str(data) + "\n\n")
error = "Y"
else:
# Deserialize response into Python object
dataObj = json.loads(data)
httpConn.close()
return dataObj
# A function to Edit Service Properties
def editService(params, serverName, serverPort, services, folder, token):
for service in services:
if (service["type"] != "MapServer"):
return
serviceName = service["serviceName"] + "." + service["type"]
if (folder == ""):
serviceURL = "/arcgis/admin/services/" + serviceName
else:
serviceURL = "/arcgis/admin/services/" + folder + "/" + serviceName
# Connect to service to get its current JSON definition
serviceObj = sendRequest(params, serverName, serverPort, serviceURL)
if (serviceObj != ""):
# Edit desired properties of the service
if (serviceObj["properties"]["schemaLockingEnabled"] == "true"):
serviceObj["properties"]["schemaLockingEnabled"] = "false"
# Serialize back into JSON
updatedSvcJson = json.dumps(serviceObj)
# Call the edit operation on the service. Pass in modified JSON.
if (folder == ""):
editSvcURL = "/arcgis/admin/services/" + serviceName + "/edit"
else:
editSvcURL = "/arcgis/admin/services/" + folder + "/" + serviceName + "/edit"
params = urllib.urlencode({'token': token, 'f': 'json', 'service': updatedSvcJson})
editData = sendRequest(params, serverName, serverPort, editSvcURL)
if (editData != ""):
print folder + "/" + serviceName + " updated successfully"
output.write(time.ctime() + ":\n" + folder + "/" + serviceName + " updated successfully" + "\n\n")
return
# A function to close the log file and send it through email
def closeLogFile():
output.write(time.ctime() + ":\n" + "Closing log file" )
output.close()
#email notification
server=<mailservername>
msg = MIMEMultipart()
msg['From'] = "arcgislicman"
msg['To'] = <email address>
msg['Date'] = formatdate(localtime=True)
msg['CC'] = <email address>
if (errors == "N"):
msg['Subject'] = "EditSchemaLock Completed Sucessfully!"
else:
msg['Subject'] = "An Error Occurred in EditSchemaLock!"
msg.attach( MIMEText(messages) )
part = MIMEBase('application', "octet-stream")
part.set_payload( open(logFile,"rb").read() )
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(logFile))
msg.attach(part)
#tolist = ["pthoopthong@co.hernando.fl.us"]
tolist = [<email addresses separated by commas>]
smtp = smtplib.SMTP(server)
smtp.sendmail("arcgislicman@co.hernando.us.fl", tolist, msg.as_string())
smtp.close()
return
# Script start
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))