Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:如何使用ConfigParser循环遍历多个ini文件?_Python_Python 3.x_Configuration_Arcgis_Ini - Fatal编程技术网

Python:如何使用ConfigParser循环遍历多个ini文件?

Python:如何使用ConfigParser循环遍历多个ini文件?,python,python-3.x,configuration,arcgis,ini,Python,Python 3.x,Configuration,Arcgis,Ini,我有点理解如何在Python中进行循环,似乎很容易说“对于这个目录中的每个文件……做点什么”。我现在很难弄清楚如何循环遍历目录中的一系列.ini文件,从中读取行,并将ini文件中的文本用作同一Python脚本中的变量。例如,a提供脚本中12个变量的值。目前,要多次运行脚本,必须将单个ini文件替换为另一个包含12个不同变量的ini文件。该脚本执行在线地图服务提供商的日常维护..问题是..我有十几个服务,我想用该脚本来管理。从脚本来看,.ini文件的名称似乎是固定的,不确定是否可以循环使用多个in

我有点理解如何在Python中进行循环,似乎很容易说“对于这个目录中的每个文件……做点什么”。我现在很难弄清楚如何循环遍历目录中的一系列.ini文件,从中读取行,并将ini文件中的文本用作同一Python脚本中的变量。例如,a提供脚本中12个变量的值。目前,要多次运行脚本,必须将单个ini文件替换为另一个包含12个不同变量的ini文件。该脚本执行在线地图服务提供商的日常维护..问题是..我有十几个服务,我想用该脚本来管理。从脚本来看,.ini文件的名称似乎是固定的,不确定是否可以循环使用多个ini文件?好消息是,脚本正在使用ConfigParser…..我希望这是有意义的

[FS_INFO]
SERVICENAME = MyMapService
FOLDERNAME = None
MXD = D:\nightly_updates\maps\MyMap.mxd
TAGS = points, dots, places
DESCRIPTION  = This is the description text
MAXRECORDS = 1000

[FS_SHARE]
SHARE = True
EVERYONE = true
ORG = true
GROUPS = None

[AGOL]
USER = user_name
PASS = pass_word1
下面的脚本正在读取上面的ini文件

# Import system modules
import urllib, urllib2, json
import sys, os
import requests
import arcpy
import ConfigParser
from xml.etree import ElementTree as ET

class AGOLHandler(object):    

    def __init__(self, username, password, serviceName, folderName):
        self.username = username
        self.password = password
        self.serviceName = serviceName
        self.token, self.http = self.getToken(username, password)
        self.itemID = self.findItem("Feature Service")
        self.SDitemID = self.findItem("Service Definition")
        self.folderName = folderName
        self.folderID = self.findFolder()

    def getToken(self, username, password, exp=60):

        referer = "http://www.arcgis.com/"
        query_dict = {'username': username,
                      'password': password,
                      'expiration': str(exp),
                      'client': 'referer',
                      'referer': referer,
                      'f': 'json'}   

        query_string = urllib.urlencode(query_dict)
        url = "https://www.arcgis.com/sharing/rest/generateToken"

        token = json.loads(urllib.urlopen(url + "?f=json", query_string).read())

        if "token" not in token:
            print token['error']
            sys.exit()
        else: 
            httpPrefix = "http://www.arcgis.com/sharing/rest"
            if token['ssl'] == True:
                httpPrefix = "https://www.arcgis.com/sharing/rest"

            return token['token'], httpPrefix

    def findItem(self, findType):
        #
        # Find the itemID of whats being updated
        #        
        searchURL = self.http + "/search"

        query_dict = {'f': 'json',
                      'token': self.token,
                      'q': "title:\""+ self.serviceName + "\"AND owner:\"" + self.username + "\" AND type:\"" + findType + "\""}    

        jsonResponse = sendAGOLReq(searchURL, query_dict)

        if jsonResponse['total'] == 0:
            print "\nCould not find a service to update. Check the service name in the settings.ini"
            sys.exit()
        else:
            print("found {} : {}").format(findType, jsonResponse['results'][0]["id"])    

        return jsonResponse['results'][0]["id"]

    def findFolder(self):
        #
        # Find the ID of the folder containing the service
        #

        if self.folderName == "None":
            return ""

        findURL = self.http + "/content/users/{}".format(self.username)

        query_dict = {'f': 'json',
                      'num': 1,
                      'token': self.token}

        jsonResponse = sendAGOLReq(findURL, query_dict)

        for folder in jsonResponse['folders']:
            if folder['title'] == self.folderName:
                return folder['id']

        print "\nCould not find the specified folder name provided in the settings.ini"
        print "-- If your content is in the root folder, change the folder name to 'None'"
        sys.exit()


def urlopen(url, data=None):
    # monkey-patch URLOPEN
    referer = "http://www.arcgis.com/"
    req = urllib2.Request(url)
    req.add_header('Referer', referer)

    if data:
        response = urllib2.urlopen(req, data)
    else:
        response = urllib2.urlopen(req)

    return response


def makeSD(MXD, serviceName, tempDir, outputSD, maxRecords):
    #
    # create a draft SD and modify the properties to overwrite an existing FS
    #    

    arcpy.env.overwriteOutput = True
    # All paths are built by joining names to the tempPath
    SDdraft = os.path.join(tempDir, "tempdraft.sddraft")
    newSDdraft = os.path.join(tempDir, "updatedDraft.sddraft")    

    arcpy.mapping.CreateMapSDDraft(MXD, SDdraft, serviceName, "MY_HOSTED_SERVICES")

    # Read the contents of the original SDDraft into an xml parser
    doc = ET.parse(SDdraft)  

    root_elem = doc.getroot()
    if root_elem.tag != "SVCManifest":
        raise ValueError("Root tag is incorrect. Is {} a .sddraft file?".format(SDDraft))

    # The following 6 code pieces modify the SDDraft from a new MapService
    # with caching capabilities to a FeatureService with Query,Create,
    # Update,Delete,Uploads,Editing capabilities as well as the ability to set the max
    # records on the service.
    # The first two lines (commented out) are no longer necessary as the FS
    # is now being deleted and re-published, not truly overwritten as is the 
    # case when publishing from Desktop.
    # The last three pieces change Map to Feature Service, disable caching 
    # and set appropriate capabilities. You can customize the capabilities by
    # removing items.
    # Note you cannot disable Query from a Feature Service.

    #doc.find("./Type").text = "esriServiceDefinitionType_Replacement" 
    #doc.find("./State").text = "esriSDState_Published"

    # Change service type from map service to feature service
    for config in doc.findall("./Configurations/SVCConfiguration/TypeName"):
        if config.text == "MapServer":
            config.text = "FeatureServer"

    #Turn off caching
    for prop in doc.findall("./Configurations/SVCConfiguration/Definition/" +
                                "ConfigurationProperties/PropertyArray/" +
                                "PropertySetProperty"):
        if prop.find("Key").text == 'isCached':
            prop.find("Value").text = "false"
        if prop.find("Key").text == 'maxRecordCount':
            prop.find("Value").text = maxRecords

    # Turn on feature access capabilities
    for prop in doc.findall("./Configurations/SVCConfiguration/Definition/Info/PropertyArray/PropertySetProperty"):
        if prop.find("Key").text == 'WebCapabilities':
            prop.find("Value").text = "Query,Create,Update,Delete,Uploads,Editing"

    # Add the namespaces which get stripped, back into the .SD    
    root_elem.attrib["xmlns:typens"] = 'http://www.esri.com/schemas/ArcGIS/10.1'
    root_elem.attrib["xmlns:xs"] ='http://www.w3.org/2001/XMLSchema'

    # Write the new draft to disk
    with open(newSDdraft, 'w') as f:
        doc.write(f, 'utf-8')

    # Analyze the service
    analysis = arcpy.mapping.AnalyzeForSD(newSDdraft)

    if analysis['errors'] == {}:
        # Stage the service
        arcpy.StageService_server(newSDdraft, outputSD)
        print "Created {}".format(outputSD)

    else:
        # If the sddraft analysis contained errors, display them and quit.
        print analysis['errors']
        sys.exit()


def upload(fileName, tags, description): 
    #
    # Overwrite the SD on AGOL with the new SD.
    # This method uses 3rd party module: requests
    #

    updateURL = agol.http+'/content/users/{}/{}/items/{}/update'.format(agol.username, agol.folderID, agol.SDitemID)

    filesUp = {"file": open(fileName, 'rb')}

    url = updateURL + "?f=json&token="+agol.token+ \
        "&filename="+fileName+ \
        "&type=Service Definition"\
        "&title="+agol.serviceName+ \
        "&tags="+tags+\
        "&description="+description

    response = requests.post(url, files=filesUp);     
    itemPartJSON = json.loads(response.text)

    if "success" in itemPartJSON:
        itemPartID = itemPartJSON['id']
        print("updated SD:   {}").format(itemPartID)
        return True
    else:
        print "\n.sd file not uploaded. Check the errors and try again.\n"  
        print itemPartJSON
        sys.exit()        


def publish():
    #
    # Publish the existing SD on AGOL (it will be turned into a Feature Service)
    #

    publishURL = agol.http+'/content/users/{}/publish'.format(agol.username)

    query_dict = {'itemID': agol.SDitemID,
              'filetype': 'serviceDefinition',
              'overwrite': 'true',
              'f': 'json',
              'token': agol.token}    

    jsonResponse = sendAGOLReq(publishURL, query_dict)

    print("successfully updated...{}...").format(jsonResponse['services'])

    return jsonResponse['services'][0]['serviceItemId']


def enableSharing(newItemID, everyone, orgs, groups):
    #
    # Share an item with everyone, the organization and/or groups
    #

    shareURL = agol.http+'/content/users/{}/{}/items/{}/share'.format(agol.username, agol.folderID, newItemID)

    if groups == None:
        groups = ''

    query_dict = {'f': 'json',
                  'everyone' : everyone,
                  'org' : orgs,
                  'groups' : groups,
                  'token': agol.token}    

    jsonResponse = sendAGOLReq(shareURL, query_dict)

    print("successfully shared...{}...").format(jsonResponse['itemId'])    



def sendAGOLReq(URL, query_dict):
    #
    # Helper function which takes a URL and a dictionary and sends the request
    #

    query_string = urllib.urlencode(query_dict)    

    jsonResponse = urllib.urlopen(URL, urllib.urlencode(query_dict))
    jsonOuput = json.loads(jsonResponse.read())

    wordTest = ["success", "results", "services", "notSharedWith", "folders"]
    if any(word in jsonOuput for word in wordTest):
        return jsonOuput    
    else:
        print "\nfailed:"
        print jsonOuput
        sys.exit()


if __name__ == "__main__":
    #
    # start
    #

    print "Starting Feature Service publish process"

    # Find and gather settings from the ini file
    localPath = sys.path[0]
    settingsFile = os.path.join(localPath, "settings.ini")

    if os.path.isfile(settingsFile):
        config = ConfigParser.ConfigParser()
        config.read(settingsFile)
    else:
        print "INI file not found. \nMake sure a valid 'settings.ini' file exists in the same directory as this script."
        sys.exit()

    # AGOL Credentials
    inputUsername = config.get( 'AGOL', 'USER')
    inputPswd = config.get('AGOL', 'PASS')

    # FS values
    MXD = config.get('FS_INFO', 'MXD')
    serviceName = config.get('FS_INFO', 'SERVICENAME')   
    folderName = config.get('FS_INFO', 'FOLDERNAME')
    tags = config.get('FS_INFO', 'TAGS')
    description = config.get('FS_INFO', 'DESCRIPTION')
    maxRecords = config.get('FS_INFO', 'MAXRECORDS')

    # Share FS to: everyone, org, groups
    shared = config.get('FS_SHARE', 'SHARE')
    everyone = config.get('FS_SHARE', 'EVERYONE')
    orgs = config.get('FS_SHARE', 'ORG')
    groups = config.get('FS_SHARE', 'GROUPS')  #Groups are by ID. Multiple groups comma separated


    # create a temp directory under the script     
    tempDir = os.path.join(localPath, "tempDir")
    if not os.path.isdir(tempDir):
        os.mkdir(tempDir)  
    finalSD = os.path.join(tempDir, serviceName + ".sd")  

    #initialize AGOLHandler class
    agol = AGOLHandler(inputUsername, inputPswd, serviceName, folderName)

    # Turn map document into .SD file for uploading
    makeSD(MXD, serviceName, tempDir, finalSD, maxRecords)

    # overwrite the existing .SD on arcgis.com

    if upload(finalSD, tags, description):

        # publish the sd which was just uploaded
        newItemID = publish()

        # share the item
        if shared:
            enableSharing(newItemID, everyone, orgs, groups)

        print "\nfinished."

如果我正确理解您的问题,您只需要在main中添加另一个循环,然后将main中的大部分内容放入新函数(在我的示例中,新函数称为“process_ini”)

因此,尝试将从您的姓名==主线到结尾的所有内容替换为:

def process_ini(fileName):
    settingsFile = os.path.join(localPath, fileName)

    if os.path.isfile(settingsFile):
        config = ConfigParser.ConfigParser()
        config.read(settingsFile)
    else:
        print "INI file not found. \nMake sure a valid 'settings.ini' file exists in the same directory as this script."
        sys.exit()

    # AGOL Credentials
    inputUsername = config.get( 'AGOL', 'USER')
    inputPswd = config.get('AGOL', 'PASS')

    # FS values
    MXD = config.get('FS_INFO', 'MXD')
    serviceName = config.get('FS_INFO', 'SERVICENAME')
    folderName = config.get('FS_INFO', 'FOLDERNAME')
    tags = config.get('FS_INFO', 'TAGS')
    description = config.get('FS_INFO', 'DESCRIPTION')
    maxRecords = config.get('FS_INFO', 'MAXRECORDS')

    # Share FS to: everyone, org, groups
    shared = config.get('FS_SHARE', 'SHARE')
    everyone = config.get('FS_SHARE', 'EVERYONE')
    orgs = config.get('FS_SHARE', 'ORG')
    groups = config.get('FS_SHARE', 'GROUPS')  #Groups are by ID. Multiple groups comma separated


    # create a temp directory under the script
    tempDir = os.path.join(localPath, "tempDir")
    if not os.path.isdir(tempDir):
        os.mkdir(tempDir)
    finalSD = os.path.join(tempDir, serviceName + ".sd")

    #initialize AGOLHandler class
    agol = AGOLHandler(inputUsername, inputPswd, serviceName, folderName)

    # Turn map document into .SD file for uploading
    makeSD(MXD, serviceName, tempDir, finalSD, maxRecords)

    # overwrite the existing .SD on arcgis.com

    if upload(finalSD, tags, description):

        # publish the sd which was just uploaded
        newItemID = publish()

        # share the item
        if shared:
            enableSharing(newItemID, everyone, orgs, groups)

        print "\nfinished."

if __name__ == "__main__":
    print "Starting Feature Service publish process"
    # Find and gather settings from the ini file
    localPath = sys.path[0]
    for fileName in ['settings.ini', 'flurb.ini', 'durf.ini']:
        process_ini(fileName)
您必须在我的示例倒数第二行的列表中写入所有ini文件名

或者,您可以通过以下代码识别目录中的所有.ini文件:

if __name__ == "__main__":
    print "Starting Feature Service publish process"
    # Find and gather settings from the ini file
    localPath = sys.path[0]
    fileNames = [os.path.join(localPath, i) for i in os.listdir(localPath) if i.endswith('.ini')]
    for fileName in fileNames:
        process_ini(fileName)

设置工作目录(例如,os.chdir(localPath))可能也会有帮助,但我已经脱离了您已有的目录。

Awesome man,谢谢!我完全按照您的建议实现了,但是if name==“main”:中的某些内容失败:返回回溯(最近一次调用最后一次):文件“update.py”,第330行,在进程ini(文件名)文件中“update.py”,第314行,在上传(finalSD,tags,description)的进程ini中:文件“update.py”,第187行,在upload updateURL=agol.http+'/content/users/{}/{}/{}/items/{}/update.格式中(agol.use rname,agol.folderID,agol.SDitemID)NameError:全局名称“agol”未定义答案的优点在于它成功读取ini文件并创建要上载的文件,只是循环的上载部分被炸了。令人困惑。@tpcolson,基于该错误,您只需传递agol to upload()。在“upload”(finalSD,tags,description)的两个位置出现在脚本中,将其替换为“上载(finalSD,tags,description,agol)”。这会生成一些新错误:回溯(最近一次调用):文件“X:\GIS\u Final\data\basedata\basemap\Maps\ArcGIS\ArcGIS\u SERVER\GRSM\u扰动\test.py”,第331行,进程ini(文件名)文件“X:\GIS\u Final\data\basedata\basemap\Maps\ArcGIS\ArcGIS\u SERVER\GRSM\u emission\test.py”,第318行,进程中\u ini newItemID=publish()文件“X:\GIS\u Final\data\basedata\basemap\Maps\ArcGIS\ArcGIS\ArcGIS\u SERVER\GRSM\u emission\test.py”,第216行,publish publish publish url=agol.http+'/content/users/{}/publish.格式(agol.username)NameError:没有定义全局名称“agol”。基本上,您只需要确保将agol传递给使用它的每个函数。在我上次的回答中,我提到了upload(),但看起来您还需要将agol添加到publish()enableSharing()。请记住,您必须同时传递和“接收”它。这意味着搜索“publish”(并将“agol”添加到括号内的项目中。对“enableSharing”()执行相同的操作。请参阅: