Source code for RPLib

from __future__ import print_function
import arcpy, smtplib, string, sys, time, os, httplib, urllib, json, getpass
import subprocess
from arcpy import env
from datetime import datetime
from email.mime.text import MIMEText
# pylint: disable-msg=C0103
# pylint: disable-msg=C0303
## email method variables
email_ON = False
email_To = ()
email_From = ""
email_Subject = ""
email_Msg = ""
email_IP = ""
email_Port = ""
email_Username = ""
email_Password = ""

## Logging variables
verboseLog = False

## recPost method variables
recpost_Log = ""

## createVersions method variables
createVersions_List = []

def Logger(Log_Loc="",):

    DATE = '%Y_%m_%d'
    TIME = '%H_%M%p'
    Script_Log = Log_Loc

    if not Script_Log == "":
        if arcpy.Exists(Script_Log):
            ScriptLog = ("{0}//ScriptLog"
                        "_{1}_{2}.txt".format(Script_Log,
                                              datetime.now().strftime(DATE),
                                              datetime.now().strftime(TIME)))
            f = open(ScriptLog, 'w')
            sys.stdout = Tee(sys.stdout, f)
        else:
            print("The specified path for storing the log file does not"
                  " exist!\n")
    else:
        print("A path for the log file location must be specified!\n")

class Tee(object):
    def __init__(self, *files):
        self.files = files
    def write(self, obj):
        for f in self.files:
            f.write(obj)

[docs]def clearworkspacecache(Workspace = None,): """ **Clears any ArcSDE workspaces from the ArcSDE workspace cache.** ================== ======== ======================================================================================= ========= Parameter Type Description Required ================== ======== ======================================================================================= ========= **Workspace** String Path to SDE connection file. Yes ================== ======== ======================================================================================= ========= **Returns: Boolean** """ try: if verifyworkspace(Workspace,"Clear Workspace Cache","Workspace"): if verifysde(Workspace,"Clear Workspace Cache"): prnt("Clearing workspace cache " "for : {0} ... ".format(Workspace)) arcpy.ClearWorkspaceCache_management(Workspace) success() return True else: return False else: return False except Exception, e: failed() Subject = " ERROR: Clear workspace cache" Msg = " Error clearing workspace cache for {0}\n".format(Workspace) print(Msg+"\n"+str(e)) if email_ON: email(Subject, Msg) return False
[docs]def pauseconnections(Workspace = None,): """ **Allows an administrator to disable the ability of nonadministrative users to make connections to an enterprise geodatabase.** ================== ======== ======================================================================================= ========= Parameter Type Description Required ================== ======== ======================================================================================= ========= **Workspace** String Path to SDE connection file. Yes ================== ======== ======================================================================================= ========= **Returns: Boolean** """ # Process: block new connections to the database try: if verifyworkspace(Workspace,"Pause Connections","Workspace"): if verifysde(Workspace,"Pause Connections"): prnt( "Blocking new connections " "for : {0} ... ".format(Workspace)) arcpy.AcceptConnections(Workspace, False) success() return True else: return False else: return False except Exception, e: failed() Subject = "ERROR: Pause connections" Msg = ( " An error occurred while trying to pause connections for {0}.\n" " Please ensure the connection file provided has the required" " permissions to pause database connections.\n Typically the sde" " user handles connections to the database.\n If you were not" " using a connection file that uses the sde username and password" " please try using a connection file which does.".format(Workspace)) print(Msg+"\n"+" "+ str(e)) if email_ON: email(Subject, Msg) return False
[docs]def resumeconnections(Workspace = None,): """ **Allows an administrator to enable the ability of nonadministrative users to make connections to an enterprise geodatabase.** ================== ======== ======================================================================================= ========= Parameter Type Description Required ================== ======== ======================================================================================= ========= **Workspace** String Path to SDE connection file. Yes ================== ======== ======================================================================================= ========= **Returns: Boolean** """ # Process: allow new connections to the database try: if verifyworkspace(Workspace,"Resume Connections","Workspace"): if verifysde(Workspace,"Resume Connections"): prnt( "Allowing new connections " "for : {0} ... ".format(Workspace)) arcpy.AcceptConnections(Workspace, True) success() return True else: return False else: return False except Exception, e: failed() Subject = "ERROR: Resume connections" Msg = (" An error occurred while trying to resume connections" " for {0}.\n Please ensure the connection file provided" " has the required permissions to resume database connections.\n" " Typically the sde user handles connections to the database.\n" " If you were not using a connection file that uses the sde" " username and password please try using a connection file" " which does.".format(Workspace)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False
[docs]def killconnections(Workspace = None,): """ **Allows an administrator to disconnect all users who are currently connected to an Enterprise geodatabase.** ================== ======== ======================================================================================= ========= Parameter Type Description Required ================== ======== ======================================================================================= ========= **Workspace** String Path to SDE connection file Yes ================== ======== ======================================================================================= ========= **Returns: Boolean** """ # Process: disconnect all users from the database. try: if verifyworkspace(Workspace,"Kill Connections","Workspace"): if verifysde(Workspace,"Kill Connections"): prnt( "Killing all connections " "for : {0} ... ".format(Workspace)) arcpy.DisconnectUser(Workspace, "ALL") success() return True else: return False else: return False except Exception, e: failed() Subject = " ERROR: Kill connections" Msg = (" Error trying to kill connections for {0}.\n" " Please ensure the connection file provided has the required" " permissions to kill database connections.\n Typically the" " sde user handles connections to the database.\n If you were" " not using a connection file that uses the sde username and" " password please try using a connection file which does." "".format(Workspace)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False
[docs]def compressgdb(Workspace = None,): """ **Compresses an enterprise geodatabase by removing states not referenced by a version and redundant rows.** ================== ======== ======================================================================================= ========= Parameter Type Description Required ================== ======== ======================================================================================= ========= **Workspace** String Path to SDE connection file. Yes ================== ======== ======================================================================================= ========= **Returns: Boolean** """ try: if verifyworkspace(Workspace,"Compress Database","Workspace"): if verifysde(Workspace,"Compress Database"): prnt("Compressing geodatabase: {0} ... ".format(Workspace)) arcpy.Compress_management(Workspace) success() return True else: return False else: return False except Exception, e: failed() Subject = " ERROR: Compressing geodatabase" Msg = " Error compressing geodatabase {0}\n".format(Workspace) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False
[docs]def createversions(Workspace = None, Versions_List = [], PublicAccess = True, ParentVerion = None,): """ **Creates a new version(s) in the specified geodatabase.** ================== ======== ======================================================================================= ========== Parameter Type Description Required ================== ======== ======================================================================================= ========== **Workspace** String Path to SDE connection file . Yes **Versions_List** List The name of the version(s) to be created. Yes **PublicAccess** Boolean The permission access level for the version. No\n * True = Public **(Default)**\n * False = Private\n * "PROTECTED" = Protected **ParentVersion** String The geodatabase, or version of a geodatabase, on which the new version will be based. No\n * None = "sde.default"\n * "" = "sde.default"\n ================== ======== ======================================================================================= ========== **Returns: Boolean** """ if verifyworkspace(Workspace,"Create Versions","Workspace"): if verifysde(Workspace,"Create Versions"): env.workspace = Workspace else: return False else: return False if len(Versions_List) == 0: Subject = " ERROR: Create versions" Msg = (" Invalid expression supplied for parameter" " Versions_List !\n The parameter cannot be an empty" " list.\n Expected: List.\n Please provide a list" " of version name(s) to be created.") print(Msg) if email_ON: email(Subject, Msg) return False else: version_name = Versions_List if PublicAccess == True: access_permission = "PUBLIC" elif PublicAccess == False: access_permission = "PRIVATE" elif PublicAccess == "PROTECTED": access_permission = "PROTECTED" else: Subject = " ERROR: Create versions" Msg = ("Invalid expression supplied for parameter PublicAccess !\n" ' Expected: True, False, or "PROTECTED" .\n' " Received: {0}".format(PublicAccess)) print(Msg) if email_ON: email(Subject, Msg) return False parent_version = "" check_parent = "" verList = [] if ParentVerion is None or len(ParentVerion) ==0: parent_version = "sde.default" else: check_parent = str(ParentVerion) check_parent = check_parent.lower() for ver in arcpy.da.ListVersions(): if ver.isOwner == True and ver.name.lower() == check_parent: parent_version = ParentVerion verList = [ver.name for ver in arcpy.da.ListVersions() if ver.isOwner == True and ver.name.lower() != parent_version.lower()] # convert Lists to strings for comparison strverList = ''.join(verList) newversions = [] existingversions = [] for version in version_name: if not str(version) in strverList: newversions.append(version) else: existingversions.append(version) if not len(existingversions) == 0: Subject = " ERROR: Create versions" Msg = (" Unable to create verion(s) {0}, already" " exist!".format(existingversions)) print(Msg) if email_ON: email(Subject, Msg) if not len(newversions) == 0: for version in newversions: try: prnt( "Creating version : {0} ... ".format(version)) arcpy.CreateVersion_management(Workspace, parent_version, version, access_permission) success() except Exception, e: failed() Subject = " Error: Create versions" Msg = (" An error occurred while trying to create" " versions for {0}.\n Please ensure the correct" " connection file is being referenced and that" " the user has permissions to create versions.\n" " Does the parent version being referenced" " exist?\n Is the correct string being passed" " for PublicAccess?\n Please review the log file" " for more detailed" " information.".format(Workspace)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False return True else: Subject = " ERROR: Create versions" Msg = (" No new versions were created.\n All versions" " specified: {0} already exist! \n".format(version_name)) print(Msg) if email_ON: email(Subject, Msg) return False
[docs]def rebuild_indexes_analyze(Workspace = None, excludeList = None, include_system = False, delta_only = True, only_versioned = True, analyze_base = True, analyze_delta = True, analyze_archive = True,): """ **Updates indexes of datasets and system tables stored in an enterprise geodatabase. Rebuilds existing attribute or spatial indexes. Updates database statistics of base tables, delta tables, and archive tables, along with the statistics on those tables indexes.** =================== ======== ======================================================================================= ========== Parameter Type Description Required =================== ======== ======================================================================================= ========== **Workspace** String Path to SDE connection file Yes **excludeList** List List of object names to exclude from being processed. No **include_system** Boolean Indicates whether statistics will be gathered on the states and state lineages tables. No\n * True = SYSTEM\n * False = NO_SYSTEM **(Default)**\n **delta_only** Boolean Indicates how the indexes will be rebuilt on the selected datasets. No\n * True = ONLY_DELTAS **(Default)**\n * False = ALL\n **only_versioned** Boolean Indicates if indexes will only be rebuilt for objects that are versioned. No\n * True = Include only versioned objects. **(Default)**\n * False = Include all database objects versioned and non-versioned.\n **analyze_base** Boolean Indicates whether the selected dataset base tables will be analyzed. No\n * True = ANALYZE_BASE **(Default)**\n * False = NO_ANALYZE_BASE\n **analyze_delta** Boolean Indicates whether the selected dataset delta tables will be analyzed. No\n * True = ANALYZE_DELTA **(Default)**\n * False = NO_ANALYZE_DELTA\n **analyze_archive** Boolean Indicates whether the selected dataset delta tables will be analyzed. No\n * True = ANALYZE_ARCHIVE **(Default)**\n * False = NO_ANALYZE_ARCHIVE\n =================== ======== ======================================================================================= ========== **Returns: Boolean** """ if verifyworkspace(Workspace,"Rebuild Indexes Analyze","Workspace"): if verifysde(Workspace,"Rebuild Indexes Analyze"): env.workspace = Workspace userName = arcpy.Describe(Workspace).connectionProperties.user else: return False else: return False if excludeList is None: excludeList = [] elif type(excludeList) is list: xList = excludeList else: Subject = " ERROR: rebuild index analyze" Msg = (" Invalid parameter found for excludeList !\n" " Expected: List.\n" " Please provide a list of objects in the geodatabse" " that you do not wish to have included in this process.") print(Msg) if email_ON: email(Subject, Msg) return False if type(include_system) is bool: if include_system is False: include_system = "NO_SYSTEM" else: include_system = "SYSTEM" else: Subject = " ERROR: rebuild index analyze" Msg = ("Invalid expression supplied for parameter include_system !\n" ' Expected: True or False .\n' " Received: {0}".format(include_system)) print(Msg) if email_ON: email(Subject, Msg) return False if type(delta_only) is bool: if delta_only is False: delta_only = "ALL" else: delta_only = "ONLY_DELTAS" else: Subject = " ERROR: rebuild index analyze" Msg = ("Invalid expression supplied for parameter delta_only !\n" ' Expected: True or False .\n' " Received: {0}".format(delta_only)) print(Msg) if email_ON: email(Subject, Msg) return False if type(only_versioned) is bool: pass else: Subject = " ERROR: rebuild index analyze" Msg = ("Invalid expression supplied for parameter only_versioned !\n" ' Expected: True or False .\n' " Received: {0}".format(delta_only)) print(Msg) if email_ON: email(Subject, Msg) return False if type(analyze_base) is bool: if analyze_base is False: analyze_base = "NO_ANALYZE_BASE" else: analyze_base = "ANALYZE_BASE" else: Subject = " ERROR: rebuild index analyze" Msg = ("Invalid expression supplied for parameter analyze_base !\n" ' Expected: True or False .\n' " Received: {0}".format(delta_only)) print(Msg) if email_ON: email(Subject, Msg) return False if type(analyze_delta) is bool: if analyze_delta is False: analyze_delta = "NO_ANALYZE_DELTA" else: analyze_delta = "ANALYZE_DELTA" else: Subject = " ERROR: rebuild index analyze" Msg = ("Invalid expression supplied for parameter analyze_delta !\n" ' Expected: True or False .\n' " Received: {0}".format(delta_only)) print(Msg) if email_ON: email(Subject, Msg) return False if type(analyze_archive) is bool: if analyze_archive is False: analyze_archive = "NO_ANALYZE_ARCHIVE" else: analyze_archive = "ANALYZE_ARCHIVE" else: Subject = " ERROR: rebuild index analyze" Msg = ("Invalid expression supplied for parameter analyze_archive !\n" ' Expected: True or False .\n' " Received: {0}".format(delta_only)) print(Msg) if email_ON: email(Subject, Msg) return False try: prnt("Gathering list of database objects...") # Types of objects that will processed. ftypes = ['Table','FeatureClass','FeatureDataset'] # Tuple of Table and FeatureClass objects. gdb_objects = [] # Tuple of FeatureDataSet objects fds_objects = [] # Tuple of versioned Table and FeatureClass objects. idx_objects = [] # Tuple of versioned FeatureDataSet objects fidx_objects = [] # Use arcpy's data access module to walk the current workspace # and gather all object specified in ftypes tuple. for dirpath, dirnames, filenames in arcpy.da.Walk(Workspace, followlinks=True, datatype=ftypes): # Loop through all objects in geodatabase and append them # to the gdb_objects tuple. for filename in filenames: gdb_objects.append(filename) # Loop through all objects in geodatabase and append them # to the fds_objects if they are of type FeatureDataSet. for dirname in dirnames: fds_objects.append(dirname) # Check to see that excludeList is not empty. if not len(excludeList) == 0: # If objects exist in excludeList compare them to gdb_objects. # If a match is found remove the object from gdb_objects. gdb_objects =[objects.upper() for objects in gdb_objects if not any(exclude.upper() for exclude in excludeList if exclude.upper() in objects.upper())] # If only_version is True if only_versioned: # Loop through gdb_objects for obj in gdb_objects: # For each object check to see if the object is versioned. if arcpy.Describe(obj).Isversioned: # If object is versioned add it to the idx_objects tuple. idx_objects.append(obj) # Loop through FeatureDataSet objects for obj in fds_objects: # For each object check to see if the object is versioned. if arcpy.Describe(obj).Isversioned: # If object is versioned add it to the fidx_objects tuple. fidx_objects.append(obj) # If verbose logging is True show arcpy.Messages. # If False print success on same line. success() except Exception, e: failed() Subject = " Error: rebuild index analyze" Msg = ( " An error occurred while trying to gather objects" " for workspace: {0}.\n Please ensure the correct connection file" " is being referenced".format(Workspace)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False # If only_versioned is True. if only_versioned: # Set initial objects to only versioned objects gdb_objects = idx_objects fds_objects = fidx_objects # Check to ensure the tuple is not empty. if not len(gdb_objects) == 0: prnt(" Beginning Rebuilding Indexes for FeatureClasses and" " Tables for user: {0} ... ".format(userName)) try: # Call Esri tool to rebuild indexes on all gdb_objects arcpy.RebuildIndexes_management(Workspace, include_system, gdb_objects, delta_only) success() # Check to ensure fds_objects is not empty. if not len(fds_objects) == 0: prnt( " Begin Analyzing FeatureDataSets" " for user: {0} ... ".format(userName)) # Call Esri tool to analyze Featuredatasets in fds_objects. arcpy.AnalyzeDatasets_management(Workspace, include_system, fds_objects, analyze_base, analyze_delta, analyze_archive) success() except Exception, e: failed() # The initial tools failed because of a permissions issue. # This will try to rerun the tools with less permissions. if "000684" in str(e): print(" User does not have permissions to work with" " system tables\n") try: prnt(" TRYING WITHOUT SYSTEM TABLES!!! Beginning" " Rebuilding Indexes for FeatureClasses and" " Tables for user: {0} ... ".format(userName)) arcpy.RebuildIndexes_management(Workspace, "NO_SYSTEM", gdb_objects, "ALL") success() if not len(fds_objects) == 0: prnt( " TRYING WITHOUT SYSTEM TABLES!!! Begin" " Analyzing FeatureDataSets for user:" " {0} ... ".format(userName)) arcpy.AnalyzeDatasets_management(Workspace, "NO_SYSTEM", fds_objects, analyze_base, analyze_delta, analyze_archive) success() return True except Exception, e: failed() Subject = " ERROR: rebuild_indexes_analyze" Msg = (" Rebuild Index and Analyze without system" " table failed for: {0}\n".format(Workspace)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False else: print(" No FeatueClasses or Tables were found" " for user: {0}".format(userName))
[docs]def reconcilepost(Workspace = None, log_folder = None, versions = None, parent_version = None, delete_version = True, all_versions = True, acquire_locks = True, abort_if_conflicts = True, by_object = True, favor_target = True, post = True,): """ **Reconciles a version or multiple versions against a target version.** ====================== ======== =============================================================================================================================================================================================================================================== ========== Parameter Type Description Required ====================== ======== =============================================================================================================================================================================================================================================== ========== **Workspace** String Path to SDE connection file. Yes **log_folder** String Path to folder where log file(s) will be stored. Yes **versions** List List of version names to be reconciled and posted. No\n **parent_version** String The geodatabase, or version of a geodatabase, which owns the version(s). No\n * None = "sde.default" **(Default)**\n * "" = "sde.default"\n **delete_version** Boolean Indicates if versions will be deleted after posting to target version. No\n * True = Delete version after posting to target version. **(Default)**\n * False = Keep version after posting to target version.\n **all_versions** Boolean Determines which versions will be reconciled when the tool is executed. No\n * True = Reconciles edit versions with the target version. **(Default)**\n * False = Reconciles versions that are blocking the target version from compressing.\n **acquire_locks** Boolean Determines whether feature locks will be acquired. No\n * True = Should be used when the intention is to post edits. **(Default)**\n * False = Should be used when the edit version will not be posted to the target version. **abort_if_conflicts** Boolean Reconcile will be aborted if conflicts are found between versions. No\n * True = Aborts the reconcile if conflicts are found. **(Default)**\n * False = Does not abort the reconcile if conflicts are found. **by_object** Boolean Describes the conditions required for a conflict to occur. No\n * True = Any changes to the same row or feature in the parent and child versions will conflict during reconcile. **(Default)**\n * False = Only changes to the same attribute of the same row or feature in the parent and child versions will be flagged as a conflict during reconcile. Changes to different attributes will not be considered a conflict during reconcile.\n **favor_target** Boolean Describes the behavior if a conflict is detected. No\n * True = Resolve in favor of the target version. **(Default)**\n * False = Resolve in favor of the edit version.\n **post** Boolean Posts the current edit session to the reconciled target version. No\n * True = Version will be posted to the target version after the reconcile. **(Default)**\n * False = Version will not be posted to the target version after the reconcile. ====================== ======== =============================================================================================================================================================================================================================================== ========== **Returns: Boolean** """ if verifyworkspace(Workspace,"Reconcile and Post","Workspace"): if verifysde(Workspace,"Reconcile and Post"): env.workspace = Workspace else: return False else: return False # parameter check reconcilepost log_folder if (log_folder == None or len(log_folder) == 0 and type(log_folder) is str ): recPost_Log = "" print("None or empty string found") if type(log_folder) is str and arcpy.Exists(log_folder): recPost_Log = log_folder # remove any trailing or leading spaces recPost_Log = recPost_Log.strip() else: Subject = " ERROR: reconcile and post" Msg = ("Invalid expression supplied for parameter log_folder !\n" " The folder location {0} cannot be found.\n" " Expected: String.\n" " Please provide a valid path to a folder.".format(log_folder)) print(Msg) if email_ON: email(Subject, Msg) return False # paramter check reconcilepost target_version if parent_version is None or len(parent_version) == 0: target_version = "sde.default" elif type(parent_version) is str and len(parent_version) != 0: target_version = str(parent_version) target_version = target_version.lower() else: Subject = " ERROR: reconcile and post" Msg = ("Invalid expression supplied for parameter parent_version !\n" " Expected: String\n" " Received: {0}\n" " Please provide the name of the" " parent/target version as a string.".format(parent_version)) print(Msg) if email_ON: email(Subject, Msg) return False # paramter check reconcilepost target_version # check to ensure parent version exist. for ver in arcpy.da.ListVersions(): if ver.isOwner == True and ver.name.lower() == target_version.lower(): target_version = parent_version #print("found target version") if len(target_version) == 0: Subject = " ERROR: reconcile and post" Msg = ("Invalid expression supplied for parameter parent_version !\n" " The parent_version specified does not exist or could not" " be found: {0}".format(parent_version)) print(Msg) if email_ON: email(Subject, Msg) return False # parameter check reconcilepost edit_versions if (versions == None or len(versions) == 0 or versions == "" ): edit_versions = [ver.name for ver in arcpy.da.ListVersions() if ver.isOwner == True and ver.name.lower() != target_version.lower()] #print("Edit versions are: {0}".format(edit_versions)) if len(edit_versions) == 0: Subject = " ERROR: reconcile and post" Msg = ("Reconcile process was not performed !\n" " The specified target version ({0}) has no edit versions" " to reconcile with.".format(target_version)) print(Msg) if email_ON: email(Subject, Msg) return False elif type(versions) is list and len(versions) != 0: edit_versions = versions else: Subject = " ERROR: reconcile and post" Msg = ("Invalid expression supplied for parameter versions !\n" " Expected: List\n" " Received: {0}\n" " Please provide a valid list of" " version names.".format(versions)) print(Msg) if email_ON: email(Subject, Msg) return False # parameter check reconcilepost delete_version if type(delete_version) is bool: if delete_version is False: with_delete = "KEEP_VERSION" else: with_delete = "DELETE_VERSION" else: Subject = " ERROR: reconcile and post" Msg = ("Invalid expression supplied for parameter delete_version !\n" ' Expected: True or False .\n' " Received: {0}".format(delete_version)) print(Msg) if email_ON: email(Subject, Msg) return False # parameter check reconcilepost all_versions if type(all_versions) is bool: if all_versions is False: reconcile_mode = "BLOCKING_VERSIONS" else: reconcile_mode = "ALL_VERSIONS" else: Subject = " ERROR: reconcile and post" Msg = ("Invalid expression supplied for parameter all_versions !\n" ' Expected: True or False .\n' " Received: {0}".format(all_versions)) print(Msg) if email_ON: email(Subject, Msg) return False # parameter check reconcilepost acquire_locks if type(acquire_locks) is bool: if acquire_locks is False: acquire_locks = "NO_LOCK_ACQUIRED" else: acquire_locks = "LOCK_ACQUIRED" else: Subject = " ERROR: reconcile and post" Msg = ("Invalid expression supplied for parameter acquire_locks !\n" ' Expected: True or False .\n' " Received: {0}".format(acquire_locks)) print(Msg) if email_ON: email(Subject, Msg) return False # parameter check reconcilepost abort_if_conflicts if type(abort_if_conflicts) is bool: if abort_if_conflicts is False: abort_if_conflicts = "NO_ABORT" else: abort_if_conflicts = "ABORT_CONFLICTS" else: Subject = " ERROR: reconcile and post" Msg = ("Invalid expression supplied for parameter" " abort_if_conflicts !\n" " Expected: True or False .\n" " Received: {0}".format(abort_if_conflicts)) print(Msg) if email_ON: email(Subject, Msg) return False # parameter check reconcilepost by_object if type(by_object) is bool: if by_object is False: conflict_definition = "BY_ATTRIBUTE" else: conflict_definition = "BY_OBJECT" else: Subject = " ERROR: reconcile and post" Msg = ("Invalid expression supplied for parameter by_object !\n" ' Expected: True or False .\n' " Received: {0}".format(by_object)) print(Msg) if email_ON: email(Subject, Msg) return False # parameter check reconcilepost favor_target if type(favor_target) is bool: if favor_target is False: conflict_resolution = "FAVOR_EDIT_VERSION" else: conflict_resolution = "FAVOR_TARGET_VERSION" else: Subject = " ERROR: reconcile and post" Msg = ("Invalid expression supplied for parameter favor_target !\n" ' Expected: True or False .\n' " Received: {0}".format(favor_target)) print(Msg) if email_ON: email(Subject, Msg) return False # parameter check reconcilepost post if type(post) is bool: if post is False: with_post = "NO_POST" else: with_post = "POST" else: Subject = " ERROR: reconcile and post" Msg = ("Invalid expression supplied for parameter post !\n" ' Expected: True or False .\n' " Received: {0}".format(post)) print(Msg) if email_ON: email(Subject, Msg) return False DATE = '%Y_%m_%d' TIME = '%H_%M%p' out_log = ("{0}/RecPostProcess" "_{1}_{2}.txt".format(recPost_Log, datetime.now().strftime(DATE), datetime.now().strftime(TIME))) #print(out_log) #print(edit_versions) # Reconcile, Abort if conflicts are found, keep all versions, write # output to logfile print("Begin reconciling all versions" " {0}\n".format(datetime.now().strftime(TIME))) try: prnt("Attempting to Reconcile and Post Versions...") arcpy.ReconcileVersions_management(Workspace, reconcile_mode, target_version, edit_versions, acquire_locks, abort_if_conflicts, conflict_definition, conflict_resolution, with_post, "KEEP_VERSION", out_log) # Process: Check if conflicts exist conflicts = arcpy.GetMessages(1) # If this error arises, there were conflicts in one or more # of the # versions. if "000084" in conflicts: # Process: Read Contents of out_log so it can be added to # email. log_file = open(out_log, 'rb') TEXT = MIMEText(log_file.read()) log_file.close() detailed_string = ("\n An error occurred while Reconciling," " Posting all versions, The first" " Reconcile and Post operation found" " conflicts. Please review and fix the" " conflicts and try again.") Subject = " ERROR: Reconcile and Post Conflicts" # Append contents of out_log to email message Msg = (" {0}\n A conflict was found for: {1}\n" " {2}".format(TEXT,Workspace,detailed_string)) print(Msg) failed() if email_ON: email(Subject, Msg) return False else: success() # This assumes the reconcile and post process was # successful. # Reconcile, Abort if conflicts are found, delete all # versions since no conflicts were found in previous # reconcile, do not write to log file if delete_version: try: prnt("Reconciling, Posting, and Deleting All" " Versions... ") arcpy.ReconcileVersions_management(Workspace, reconcile_mode, target_version, edit_versions, acquire_locks, abort_if_conflicts, conflict_definition, conflict_resolution, with_post, with_delete) success() log_file = open(out_log, 'rb') TEXT = MIMEText(log_file.read()) log_file.close() Subject = (" Success: Reconcile, Post, and" " Delete Versions") Msg = ("{0}\n" " Reconciling, Posting, and Deleting all" " versions was successful".format(TEXT)) if email_ON: email(Subject, Msg) return True except Exception, e: failed() # Process: Read Contents of out_log so it can be # added to email. log_file = open(out_log, 'rb') TEXT = MIMEText(log_file.read()) log_file.close() detailed_string = ( "\n An error occurred while Reconciling, Posting," " and Deleting all versions.\n The first Reconcile" " and Post operation was successful.\n Although" " while attempting to reconcile, post, and delete" " all versions an error was encountered.\n Please" " ensure no connections were being made to the" " database during this time and that no versions" " were in use and try again.") Subject = " Error: Reconcile and Post" Msg = ("{0}\n" " An error occurred while Reconciling," " Posting, and Deleting all versions" "".format(TEXT,detailed_string)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False else: print(" The option to delete_versions was disabled.\n") except Exception, e: print("Failed\n") # Process: Read Contents of out_log so it can be added to email. log_file = open(out_log, 'rb') TEXT = MIMEText(log_file.read()) log_file.close() detailed_string = ( "\n The first Reconcile and Post was not successful.\n Please" " ensure you are using the proper connection file for the owner" " of the versions.\n Additionally ensure there were no active" " connections or versions in use during the Reconcile and Post" " process and try again.") Subject = " Error: Reconcile and Post" Msg = ("{0}\n" "An error occurred while Reconciling and Posting" "All Versions.\n {1}".format(TEXT,detailed_string)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False
[docs]def truncateappend(SourceObject = None, DestinationObject = None, SourceObjectCount = None, ObjectsSchemaTest = False, DestUpdateField = None, FieldMappings = None, Subtype = None,): """ **Truncates and appends data from one object to another.** ====================== ============= ==================================================================================================== ========== Parameter Type Description Required ====================== ============= ==================================================================================================== ========== **SourceObject** String Path to the source geodatabase object. Yes **DestinationObject** String Path to the destination/target geodatabase object. Yes **SourceObjectCount** Integer Number of records that must be in the SourceObject before beginning the process. No\n * None = 0 **(Default)** **ObjectsSchemaTest** Boolean The schema/fields of the input data must match the schema/fields of the target data. No\n * True = Input schema must match the schema of the target.\n * False = Input schema do not have to match that of the target dataset. **(Default)** **DestUpdateField** String Provide the name of a field in the DestinationObject. No\n * The field must be of type Date.\n * After data is appended this field will be calculated with the current date and time. **FieldMappings** Field Mapping Can only be used if ObjectsSchemaTest is False. No **Subtype** String A subtype description to assign that subtype to all new data that is appended to the target dataset. No ====================== ============= ==================================================================================================== ========== **Returns: Boolean** """ print("Begin Truncate Append.\n") prnt(" Checking if Source exist...") if verifyobject(SourceObject,"Truncate Append","SourceObject"): Source = SourceObject success() else: failed() return False prnt(" Checking if Destination exist...") if verifyobject(DestinationObject,"Truncate Append","DestinationObject"): Destination = DestinationObject success() else: failed() return False # parameter check truncate and append SourceObjectCount if SourceObjectCount is None: SourceCount = 0 elif SourceObjectCount == "": SourceCount = 0 elif type(SourceObjectCount) is str and len(SourceObjectCount) != 0: SourceCount = int(SourceObjectCount) elif type(SourceObjectCount) is int: SourceCount = SourceObjectCount else: Subject = " ERROR: truncate and append" Msg = ("Invalid expression supplied for parameter SourceObjectCount !\n" " The parameter can be:\n" ' None, "", an integer, or an integer within double quotes.\n' " Please provide a user defined value like below.\n" ' None or "" or 1 or "1"') print(Msg) if email_ON: email(Subject, Msg) return False prnt(" Checking count for Source...") getCount = int(arcpy.GetCount_management(Source).getOutput(0)) print("{0}\n".format(getCount)) prnt(" Checking if {0} >= {1}...".format(getCount, SourceCount)) if getCount >= int(SourceCount): success() prnt(" Checking if destination workspace is SDE or Local GDB...") else: failed() Subject = " ERROR: truncate and append" Msg = ("Source object did not meet the requirement specified.\n" " The Source object did not have enough rows to continue." ) print(Msg) if email_ON: email(Subject, Msg) return False if not ".sde" in Destination: print("Local\n") prnt(" Checking for exclusive schema lock on destination...") if arcpy.TestSchemaLock(Destination): success() else: failed() Subject = " ERROR: Truncate Append" Msg = (" Could not acquire a schema lock for: {0}," " might be in use.\n".format(Destination)) print(Msg) if email_ON: email(Subject, Msg) return False else: print("SDE\n") prnt(" Checking that workspace is not versioned...") if not arcpy.Describe(Destination).isVersioned: success() else: failed() Subject = " ERROR: Truncate Append" Msg = " Data cannot be versioned {0}.\n".format(Destination) print(Msg) if email_ON: email(Subject, Msg) return False # parameter check truncate and append ObjectsSchemaTest if type(ObjectsSchemaTest) is bool: if ObjectsSchemaTest is False: SchemaTest = "NO_TEST" else: SchemaTest = "TEST" else: Subject = " ERROR: truncate and append" Msg = ("Invalid expression supplied for parameter ObjectsSchemaTest !\n" ' Expected: True or False .\n' " Received: {0}".format(ObjectsSchemaTest)) print(Msg) if email_ON: email(Subject, Msg) return False # parameter check truncate and append DestUpdateField if type(DestUpdateField) is str and len(DestUpdateField) != 0: prnt(" Checking if DestUpdateField is of type Date...") destfields = arcpy.ListFields(Destination) for field in destfields: fieldname = str(field.name) if fieldname.upper() == str.upper(DestUpdateField): DestUpdateField = fieldname FieldType = field.type if FieldType == "Date": success() else: failed() Subject = " ERROR: truncate and append" Msg = ("Invalid parameter supplied for DestUpdateField !\n" " Expected: (string) Field Name, of type (Date) .\n" " Received: {0} type: {1}".format(DestUpdateField, FieldType)) print(Msg) if email_ON: email(Subject, Msg) return False else: Subject = " ERROR: truncate and append" Msg = ("Invalid expression supplied for parameter DestUpdateField !\n" ' Expected: (string) Field Name .\n' " Received: {0}".format(DestUpdateField)) print(Msg) if email_ON: email(Subject, Msg) return False try: prnt(" Truncating Destination table...") arcpy.TruncateTable_management(Destination) success() except Exception, e: failed() Subject = " ERROR: Truncate Append" Msg = (" Error occurred while Truncating:" " {0}\n".format(Destination)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False try: prnt(" Appending Source to Destination...") arcpy.Append_management(Source, Destination, SchemaTest, FieldMappings, Subtype) success() except Exception, e: failed() Subject = " ERROR: Truncate Append" Msg = (" Error occurred while Appending data to:" " {0}\n".format(Destination)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False if len(DestUpdateField) !=0: prnt(" Calculating {0} with current date...".format(DestUpdateField)) try: arcpy.CalculateField_management(Destination, DestUpdateField, "calcDay( !IMPDATE! )", "PYTHON_9.3", "def calcDay(dateField):\\n " "dateValue = datetime.datetime.now()\\n " "return dateValue") success() print("End Truncate Append.\n") return True except Exception, e: failed() Subject = " ERROR: Truncate Append" Msg = (" Error occurred while calculating" " {0}\n".format(UpdateField)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False else: print("No\n")
[docs]def syncreplicas(ParentGDB = None, ChildGDB = None, ReplicaName = None, GDB1_TO_2 = True, FAVOR_GDB1 = True, BY_OBJECT = True, DO_NOT_RECONCILE = True,): """ **Synchronizes updates between two replica geodatabases in a direction specified by the user.** ====================== ============= ========================================================================================================== ========== Parameter Type Description Required ====================== ============= ========================================================================================================== ========== **ParentGDB** String The geodatabase hosting the replica to synchronize, may be local or remote. Yes **ChildGDB** String The geodatabase hosting the relative replica, geodatabase may be local or remote. Yes **ReplicaName** String Yes\n A valid replica with a parent contained within one input geodatabase and a child in the other input geodatabase. **GDB1_TO_2** Boolean No\n The direction in which you want changes to be sent from geodatabase 1 to geodatabase 2, from geodatabase 2 to geodatabase 1, or to send changes in both directions. For check-out/check-in replicas or one-way replicas there is only one appropriate direction. If the replica is two-way then any of the three choices are available.\n * True = FROM_GEODATABASE1_TO_2 -Parent to Child. **(Default)**\n * False = FROM_GEODATABASE2_TO_1 -Child to Parent.\n * "BOTH" = BOTH_DIRECTIONS **(overrides Boolean)**\n **FAVOR_GDB1** Boolean Specifies how conflicts are resolved when they are encountered. No\n * True = IN_FAVOR_OF_GDB1 -Conflicts resolve in favor of the PARENTGDB. **(Default)**\n * False = IN_FAVOR_OF_GDB2 -Conflicts resolve in favor of the CHILDGDB.\n * "MANUAL" = MANUAL, Manually resolve conflicts in the versioning environment. **(overrides Boolean)**\n **BY_OBJECT** Boolean Specifies how you would like to define conflicts. No\n * True = BY_OBJECT -Detects conflicts by row. **(Default)**\n * False = BY_ATTRIBUTE -Detects conflicts by column.\n **DO_NOT_RECONCILE** Boolean No\n Indicates whether to automatically reconcile once data changes are sent to the parent replica if there are no conflicts present. This option is only available for check-out/check-in.\n * True = DO_NOT_RECONCILE -Do not reconcile. **(Default)**\n * False = RECONCILE -Reconcile\n ====================== ============= ========================================================================================================== ========== **Returns: Boolean** """ if verifyworkspace(ParentGDB,"Sync Replicas","ParentGDB"): if verifysde(ParentGDB,"Sync Replicas"): Parent = ParentGDB else: return False else: return False if verifyworkspace(ChildGDB,"Sync Replicas","ChildGDB"): Child = ChildGDB else: return False # parameter check syncreplica ReplicaName if not (ReplicaName == None and len(ReplicaName) != 0 and type(ReplicaName) is str ): repname = ReplicaName else: Subject = " ERROR: Sync Replicas" Msg = ("Invalid expression supplied for parameter ReplicaName !\n" " The parameter cannot be None or empty.\n" " Expected: String.\n" " Please provide the name for a Replica within the geodatabase.") print(Msg) if email_ON: email(Subject, Msg) return False # parameter check syncreplica ReplicaName in ParentGDB for replica in arcpy.da.ListReplicas(ParentGDB): repname = str(replica.name) if string.upper(ReplicaName) in repname.upper(): #print("Found a match") RepName = repname #print(RepName) else: Subject = " ERROR: Sync Replica" Msg = ("Invalid expression supplied for parameter ReplicaName !\n" " The replica name was not found in the ParentGDB.\n") print(Msg) if email_ON: email(Subject, Msg) return False # parameter check syncreplica ReplicaName in ChildGDB for replica in arcpy.da.ListReplicas(ChildGDB): repname = str(replica.name) if string.upper(ReplicaName) in repname.upper(): #print("Found a match") #print(RepName) continue else: Subject = " ERROR: Sync Replica" Msg = ("Invalid expression supplied for parameter ReplicaName !\n" " The replica name was not found in the ChildGDB.\n") print(Msg) if email_ON: email(Subject, Msg) return False # parameter check syncreplica GDB1_TO_2 if type(GDB1_TO_2) is bool: if GDB1_TO_2 == True: in_direction = "FROM_GEODATABASE1_TO_2" elif GDB1_TO_2 == False: in_direction = "FROM_GEODATABASE2_TO_1" elif string.upper(GDB1_TO_2) == "BOTH": in_direction = "BOTH" else: Subject = " ERROR: Sync Replica" Msg = ("Invalid expression supplied for parameter GDB1_TO_2 !\n" ' Expected: True, False, or "BOTH" .\n' " Received: {0}".format(GDB1_TO_2)) print(Msg) if email_ON: email(Subject, Msg) return False else: Subject = " ERROR: Sync Replica" Msg = ("Invalid expression supplied for parameter GDB1_TO_2 !\n" ' Expected: True, False, or "BOTH" .\n' " Received: {0}".format(GDB1_TO_2)) print(Msg) if email_ON: email(Subject, Msg) return False # parameter check syncreplica FAVOR_GDB1 if type(FAVOR_GDB1) is bool: if FAVOR_GDB1 == True: conflict_policy = "IN_FAVOR_OF_GDB1" elif FAVOR_GDB1 == False: conflict_policy = "IN_FAVOR_OF_GDB2" elif string.upper(FAVOR_GDB1) == "MANUAL": conflict_policy = "MANUAL" else: Subject = " ERROR: Sync Replica" Msg = ("Invalid expression supplied for parameter FAVOR_GDB1 !\n" 'Expected: True or False or "MANUAL" \n' 'Received: {0}'.format(FAVOR_GDB1)) print(Msg) if email_ON: email(Subject, Msg) return False else: Subject = " ERROR: Sync Replica" Msg = ("Invalid expression supplied for parameter FAVOR_GDB1 !\n" 'Expected: True or False or "MANUAL" \n' 'Received: {0}'.format(FAVOR_GDB1)) print(Msg) if email_ON: email(Subject, Msg) return False # parameter check syncreplica BY_OBJECT if type(BY_OBJECT) is bool: if BY_OBJECT == True: conflict_definition = "BY_OBJECT" elif BY_OBJECT == False: conflict_definition = "BY_ATTRIBUTE" else: Subject = " ERROR: Sync Replica" Msg = ("Invalid expression supplied for parameter BY_OBJECT !\n" 'Expected: True or False \n' 'Received: {0}'.format(BY_OBJECT)) print(Msg) if email_ON: email(Subject, Msg) return False else: Subject = " ERROR: Sync Replica" Msg = ("Invalid expression supplied for parameter BY_OBJECT !\n" 'Expected: True or False \n' 'Received: {0}'.format(BY_OBJECT)) print(Msg) if email_ON: email(Subject, Msg) return False # parameter check syncreplica DO_NOT_RECONCILE if type(DO_NOT_RECONCILE) is bool: if DO_NOT_RECONCILE == True: reconcile = "DO_NOT_RECONCILE" elif DO_NOT_RECONCILE == False: reconcile = "RECONCILE" else: Subject = " ERROR: Sync Replica" Msg = ("Invalid expression supplied for " "parameter DO_NOT_RECONCILE !\n" 'Expected: True or False \n' 'Received: {0}'.format(DO_NOT_RECONCILE)) print(Msg) if email_ON: email(Subject, Msg) return False else: Subject = " ERROR: Sync Replica" Msg = ("Invalid expression supplied for " "parameter DO_NOT_RECONCILE !\n" 'Expected: True or False \n' 'Received: {0}'.format(DO_NOT_RECONCILE)) print(Msg) if email_ON: email(Subject, Msg) return False prnt("Synchronizing replica {0}...".format(RepName)) try: arcpy.SynchronizeChanges_management(ParentGDB, RepName, ChildGDB, in_direction, conflict_policy, conflict_definition, reconcile) success() return True except Exception, e: print("Failed\n") if "000622" or "000800" in str(e): print(" An error was encountered while trying to synchronize.\n") print(" Consider setting DO_NOT_RECONCILE parameter to True.\n") print("{0}".format(str(e))) prnt(" Attempting to synchronize without reconciling...") try: arcpy.SynchronizeChanges_management(ParentGDB, RepName, ChildGDB, in_direction, conflict_policy, conflict_definition, "DO_NOT_RECONCILE") success() return True except Exception, e: failed() Subject = " ERROR: Sync Replica" Msg = ("Trying to synchronize changes failed.\n" "An attempt was made to synchronize with reconcile and " "failed.\n" "An attempt was also made to synchronize without " " reconciling and also failed.\n" "Please ensure all parameters are valid and try again." ) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False
[docs]def executesql(Workspace = None, SQLStatement = None,): """ **Execute one or multiple SQL statements against an enterprise geodatabase.** ====================== ======== =============================================================================================================================================================================================================================================== ========== Parameter Type Description Required ====================== ======== =============================================================================================================================================================================================================================================== ========== **Workspace** String Path to SDE connection file. Yes **SQLStatement** String String of SQL statements to execute, statements separated by a semi-colon Yes ====================== ======== =============================================================================================================================================================================================================================================== ========== **Returns: Boolean** """ try: # Make data path relative if verifysde(Workspace,"executesql"): arcpy.env.workspace = Workspace sde_conn = arcpy.ArcSDESQLExecute(Workspace) # Get the SQL statements, separated by ; from a text string. sql_statement = SQLStatement sql_statement_list = sql_statement.split(";") # Encode statements as UTF-8 sql_statement_list = utf8ify(sql_statement_list) sde_return = True for sql in sql_statement_list: # Check that item in list is not empty if len(sql) != 0: print("+++++++++++++++++++++++++++++++++++++++++\n") print("Execute SQL Statement: {0}\n".format(sql)) sde_return = sde_conn.execute(sql) print("{0}\n".format(sde_return)) if isinstance(sde_return, list): print("Number of rows returned by query: " "{0} rows\n".format(len(sde_return))) if sde_return: print("SQL statement: {0} SUCCESS.\n".format(sql)) print("+++++++++++++++++++++++++++++++++++++++++\n") return True except Exception as e: print("SQL statement: {0} FAILED.\n".format(sql)) print("+++++++++++++++++++++++++++++++++++++++++\n") err = unicode(e.message).encode("utf-8") Subject = " ERROR: executesql" Msg = ("An error occurred while running the function" " executesql !\n This is this error that was encountered:" " {0}.\n Please ensure the sql code is correct.".format(err)) print(Msg) if email_ON: email(Subject, Msg) return False
[docs]def controlservices(Folder=None, Operation=None, ServerName=None, UserName=None, Password=None,): """ **Manage individual ArcGIS Server services at the folder level or through the Windows Services Console by stopping or starting the main ArcGIS Server service.** ====================== ============= ============================================================================================================ ========== Parameter Type Description Required ====================== ============= ============================================================================================================ ========== **Folder** String Yes\n The folder containing the services you wish to stop or start on your ArcGIS Server.\n * "ALL" = Will perform the Operation on the main ArcGIS Server service through the Windows Services Console. **Note "ALL" should only be used on machines running Windows Server.**\n **Operation** String Yes\n Specify the operation you wish to perform on the service(s).\n * "START" = Will Start services.\n * "STOP" = Will Stop services.\n **ServerName** String Yes\n The name or IP address of the server where ArcGIS Server is running.\n **UserName** Boolean Yes\n Specify an administrative user for ArcGIS Server.\n **Password** Boolean Yes\n Specify the administrative user password for ArcGIS Server.\n ====================== ============= ============================================================================================================ ========== **Returns: Boolean** """ # Ask for admin/publisher user name and password username = UserName password = Password # Ask for server name serverName = ServerName serverPort = 6080 folder = Folder stopOrStart = Operation if string.upper(folder) == "ALL": if string.upper(stopOrStart) == "STOP": try: os.system('sc \\\\{0} stop "ArcGIS Server"'.format(serverName)) success() return True except Exception, e: failed() Subject = " ERROR: control services" Msg = (" Error occurred while stopping ArcGIS Server" " for: {0}\n".format(serverName)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False if string.upper(stopOrStart) == "START": try: os.system('sc \\\\{0} start "ArcGIS Server"'.format(serverName)) success() return True except Exception, e: failed() Subject = " ERROR: control services" Msg = (" Error occurred while starting ArcGIS Server" " for: {0}\n".format(serverName)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False if not len(folder) == 0: if not username == None: if not password == None: # Print some info print("\nThis tool is a sample script that stops or starts" " all services in a folder.\n") # Check to make sure stop/start parameter is a valid value if [str.upper(stopOrStart) != "START" and str.upper(stopOrStart) != "STOP"]: print(" Invalid STOP/START parameter entered\n") return False # Get a token token = getToken(username, password, serverName, serverPort) #if token == "": if not token: return False else: # Construct URL to read folder if str.upper(folder) == "ROOT": folder = "" else: folder += "/" folderURL = "/arcgis/admin/services/" + folder # This request only needs the token and the response formatting parameter params = urllib.urlencode({'token': token, '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", folderURL, params, headers) # Read response response = httpConn.getresponse() if (response.status != 200): httpConn.close() print(" Could not read folder information.\n") return False else: data = response.read() # Check that data returned is not an error object if not assertJsonSuccess(data): print(" Error when reading folder" " information. {0}\n".format(str(data))) return False else: print(" Processed folder information successfully." " Now processing services...\n") # Deserialize response into Python object dataObj = json.loads(data) httpConn.close() # Loop through each service in the folder and stop or # start it for item in dataObj['services']: fullSvcName = item['serviceName'] + "." + item['type'] # Construct URL to stop or start service, then make the request stopOrStartURL = "/arcgis/admin/services/" + folder + fullSvcName + "/" + stopOrStart httpConn.request("POST", stopOrStartURL, params, headers) # Read stop or start response stopStartResponse = httpConn.getresponse() if (stopStartResponse.status != 200): httpConn.close() print(" Error while executing stop or start." " Please check the URL and try again.\n") return False else: stopStartData = stopStartResponse.read() # Check that data returned is not an error # object if not assertJsonSuccess(stopStartData): if str.upper(stopOrStart) == "START": print(" Error returned when starting" " service {0}.\n" "".format(fullSvcName)) return False else: print(" Error returned when stopping" " service {0}.\n" "".format(fullSvcName)) return False print(stopStartData) else: print(" Service {0} processed" " successfully.\n" "".format(fullSvcName)) return True httpConn.close() # Clean Up # del username del password del serverName del serverPort del folder del stopOrStart # A function to generate a token given username, password and the adminURL.
def getToken(username, password, serverName, serverPort): """ Helper function for controlservices function. A token is needed to verify authentication to manage ArcGIS Server services. All parameters are either passed by the controlservices function and or are otherwise hardcoded. Note if you named your instance anything other than arcgis please see the tokenURL and change to the name of your instance. Returns: Boolean """ # 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 try: httpConn = httplib.HTTPConnection(serverName, serverPort) httpConn.request("POST", tokenURL, params, headers) except Exception, e: failed() Subject = " ERROR: control services" ErrMsg = (" Could not generate a token with the username and password" " provided. \n Also check that the server name/ip address" " provided is valid.") Msg = (" Error connecting to {0} on port 6080.\n" " {1}\n".format(serverName,ErrMsg)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False # Read response response = httpConn.getresponse() if (response.status != 200): httpConn.close() print(" Error while fetching tokens from admin URL.\n" " Please check the URL and try again.") return False 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'] def assertJsonSuccess(data): """ A function that checks that the input JSON object is not an error object. Returns: Boolean """ obj = json.loads(data) if 'status' in obj and obj['status'] == "error": print("Error: JSON object returns an error. " + str(obj)) return False else: return True
[docs]def deletefilesolderthan(Number_Of_Days = 0, FolderLocation = "",): """ **Manages the cleanup of logfiles generated by RPLib.** ================== ======== ======================================================================================= ========= Parameter Type Description Required ================== ======== ======================================================================================= ========= **Number_Of_Days** Integer Files that are so many days older than the current day will be deleted. Yes **FolderLocation** String The folder where the logfiles are being stored. Yes ================== ======== ======================================================================================= ========= **Returns: Boolean** """ path = FolderLocation days = Number_Of_Days if not isinstance(days, int): days = int(days) if arcpy.Exists(path): try: prnt("Deleting files older than {0} days...".format(days)) now = time.time() for f in os.listdir(path): nf= os.path.join(path, f) if os.stat(nf).st_mtime < now - days * 86400: if os.path.isfile(nf): os.remove(nf) success() return True except Exception, e: failed() Subject = " ERROR: delete files older than" Msg = (" An error occurred while trying to delete files in" " {0}\n".format(path)) print(Msg + "\n" + " " + str(e)) if email_ON: email(Subject, Msg) return False else: print("The path specified does not exist!") return False
def verifysde(Workspace,functionName,): """ Helper function to verify that the workspace specified exist and that it is an SDE database. All parameters are passed from other functions. Returns: Boolean """ desc = arcpy.Describe(Workspace) # Describe function property workspaceFactoryProgID for SDE databases. sdewrkspc = "esriDataSourcesGDB.SdeWorkspaceFactory.1" # Check if workspace is an SDE database. if desc.workspaceFactoryProgID != sdewrkspc: Subject = " ERROR: {0}".format(functionName) Msg = (" ERROR: {0}\n" " This tool only works with SDE databases.\n" " Please supply a valid path to an SDE database.\n" " Received: {1}\n" " Type: {2}\n".format(functionName, Workspace, desc.workspaceFactoryProgID)) print(Msg) if email_ON: email(Subject, Msg) return False else: return True def verifyworkspace(Workspace,functionName,ParameterName): """ Helper function to verify that the workspace specified exist. All parameters are passed from other functions. Returns: Boolean """ if (Workspace == None or len(Workspace) == 0 or type(Workspace) is not str): Subject = " ERROR: {0}".format(functionName) Msg = (" ERROR: {0}\n" " Invalid expression supplied for parameter {1} !\n" " The parameter cannot be None or empty.\n" " Expected: String.\n" " Please provide a valid path to an enterprise" " geodatabase".format(functionName,ParameterName)) print(Msg) if email_ON: email(Subject, Msg) return False if not arcpy.Exists(Workspace): Subject = " ERROR: {0}".format(functionName) Msg = (" Workspace {0} does not exist".format(Workspace)) print(Msg) if email_ON: email(Subject, Msg) return False else: return True def verifyobject(Object,functionName,ParameterName): """ Helper function to verify that an object specified exists. All parameters are passed from other functions. Returns: Boolean """ if not (Object == None and len(Object) != 0 and type(Object) is str ): if arcpy.Exists(Object): return True else: Subject = " ERROR: {0}".format(functionName) Msg = (" {0} {1} does not exist".format(ParameterName,Object)) print(Msg) if email_ON: email(Subject, Msg) return False else: Subject = " ERROR: {0}".format(functionName) Msg = ("Invalid expression supplied for parameter: {0} !\n" " The parameter cannot be None or empty.\n" " Expected: String.\n" " Please provide a valid path to a geodatabase" " object like a featureclass or table.".format(Object)) print(Msg) if email_ON: email(Subject, Msg) return False def success(): """ Helper function to show that an operation ran successfully. Also handles the type of message returned, if verbose logging is enabled the full arcpy messages are returned. If verbose logging is disabled a simple message of Success is returned. """ msg = "\n" + arcpy.GetMessages() + "\n" if verboseLog else "Success\n" print(msg) def failed(): """ Helper function to show that an operation failed. Also handles the type of message returned, if verbose logging is enabled the full arcpy messages are returned. If verbose logging is disabled a simple message of Failed is returned. """ msg = "\n" + arcpy.GetMessages() + "\n" if verboseLog else "Failed\n" print(msg) def prnt(statement): """ Helper function to show messages returned at the end of a line. """ print(statement,end="") def utf8ify(list): '''Encode a list of strings in utf8''' return [item.encode('utf8') for item in list] def email(Subject,Msg): """ Helper function to send detailed information about when a function succeeds or fails. """ email_Subject = Subject email_Msg = Msg # take the email list and use it to send an email to connected users. COMMASPACE = ', ' # Prepare actual message #*Deprecated method for joining email elements together ## BODY = string.join(( ## "From: %s" % email_From, ## "To: %s" % COMMASPACE.join(email_To), ## "Subject: %s" % email_Subject , ## "", ## email_Msg ## ), "\n") # normalize newlines to CR+LF, as required by SMTP headers = (('From', email_From), ('To', COMMASPACE.join(email_To)), ('Subject', email_Subject)) body = email_Msg.replace("\r\n", "\n").replace("\n", "\r\n") msg = '\r\n'.join("%s: %s" % kv for kv in headers) + '\r\n'*2 + body # Send the mail server = smtplib.SMTP(email_IP,int(email_Port)) # If Authentication is required specify in the 2 lines below username = email_Username password = email_Password # Ping the server to do a handshake and authenticate server.ehlo() server.starttls() server.ehlo() if not username: if not password: try: # Send the email and exit connection to smtp server server.sendmail(email_From, [email_To], msg) server.quit() except: print(" Authentication may be required to send emails from this" " SMTP server.\n Please try supplying username and" " password.\n If supplying username and password does" " not work contact your system administrator and verify" " the IP address and PORT numbers are correct.") else: try: server.login(username,password) # Send the email and exit connection to smtp server server.sendmail(email_From, [email_To], msg) server.quit() except: print(" Authentication may have failed for this SMTP server.\n" " Please verify the username and password.\n If username" " and password are correct consider contacting your system" " administrator to verify the IP address and PORT numbers" " are correct.\n Also ensure that authentication is required," " try leaving username and password blank and try again.")
[docs]def emaillog(Subject=None): """ **Emails the contents of the current log file.** **Should be run at end of script.** **Creates a copy of the current log file called LastRun.txt.** ====================== ======== =============================================================================================================================================================================================================================================== ========== Parameter Type Description Required ====================== ======== =============================================================================================================================================================================================================================================== ========== **Subject** String Path to SDE connection file. No ====================== ======== =============================================================================================================================================================================================================================================== ========== **Returns: Boolean** """ if Subject is None or len(Subject) == 0: SUBJECT = "GIS Detailed Log" elif type(Subject) is str and len(Subject) != 0: SUBJECT = Subject else: Subject = " ERROR: emaillog" Msg = ("Invalid expression supplied for parameter Subject !\n" " The parameter must be of type string.\n" " Expected: String.\n" " Received: {0}".format(Subject)) print(Msg) if email_ON: email(Subject, Msg) return False global ScriptLog #print(ScriptLog) oldfile = str(ScriptLog) filename = os.path.basename(ScriptLog) lastrun = "LastRun.txt" newfilename = oldfile.replace(filename,lastrun) #print(newfilename) if arcpy.Exists(ScriptLog): if arcpy.Exists(newfilename): arcpy.Delete_management(newfilename) arcpy.Copy_management(oldfile,newfilename) else: arcpy.Copy_management(oldfile,newfilename) # Process: Open and Read script log file contents into MIME Text. # fp = open(ScriptLog, 'rb') TEXT = fp.read() fp.close() # Process: Format email and include contents from ScriptLog, then send email. # MSG = "Auto generated Message.\n GIS Detailed Log.\n{0}".format(TEXT) email(SUBJECT,MSG) return True else: print("Logfile does not exist {0}".format(newfilename)) return False
def catch_errors(func): """Decorator function to support error handling.""" def decorator(*args, **kwargs): """Decorator function""" try: f = func(*args, **kwargs) return f except Exception: tb = sys.exc_info()[2] tbInfo = traceback.format_tb(tb)[-1] print('PYTHON ERRORS:\n%s\n%s: %s\n' % (tbInfo, sys.exc_type, sys.exc_value)) gp_errors = arcpy.GetMessages(2) if gp_errors: print('GP ERRORS:\n%s\n' % gp_errors) # End decorator function return decorator # End catch_errors function