Skip To Content

예시: 콘텐츠 복사

해당 예시에서는 한 포털 (A)의 구성원이 소유한 모든 콘텐츠를 다른 포털 (B)로 복사합니다. 포털 A의 콘텐츠 소유권이 포털 B의 지정된 계정으로 양도됩니다. 이는 포털이 2개인 기관에 유용합니다. 포털 하나는 내부용이고 다른 하나는 외부용이거나, 개발 및 프로덕션 환경을 구현하는 기관을 예로 들 수 있습니다. 또한 해당 스크립트를 사용하여 ArcGIS Enterprise에서 ArcGIS Online으로 콘텐츠를 이동하거나 그 반대로 수행할 수 있습니다.

스크립트를 실행할 때 다음과 같은 정보를 지정해야 합니다.

  • 첫 번째 포털 (A)에 접근하는 데 사용되는 URL. 이는 ArcGIS Web Adaptor URL(예: https://webadaptorA.domain.com/arcgis) 또는 포털을 호스팅하는 머신의 URL(예: https://portalA.domain.com:7443/arcgis)이 될 수 있습니다. URL을 지정할 때 머신의 정규화된 도메인 이름을 포함해야 합니다.
  • 포털 A에 대한 관리 권한을 가진 계정의 사용자 이름과 비밀번호.
  • 포털 A에서 포털 B로 복사되는 콘텐츠를 소유한 계정의 사용자 이름(예시: sarah).
  • 두 번째 포털 (B)에 접근하는 데 사용되는 URL. 이는 ArcGIS Web Adaptor URL(예: https://webadaptorB.domain.com/arcgis) 또는 포털을 호스팅하는 머신의 URL(예: https://portalB.domain.com:7443/arcgis)이 될 수 있습니다. URL을 지정할 때 머신의 정규화된 도메인 이름을 포함해야 합니다.
  • 포털 B에 대한 관리 권한을 가진 계정의 사용자 이름과 비밀번호.
  • 포털 (A)에서 포털 (B)로 복사되는 콘텐츠를 소유하게 될 계정의 사용자 이름(예시: robert).
  • 콘텐츠가 복사될 포털 B의 구성원 폴더. 해당 위치는 항상 루트 폴더(/)입니다. 루트 폴더 아래의 하위 폴더에는 콘텐츠를 복사할 수 없습니다.

다음 예시에서는 포털 A의 구성원인 sarah가 소유한 모든 콘텐츠를 포털 B의 구성원인 robert에게 복사합니다.

python copyContent.py https://webadaptorA.domain.com/arcgis admin pass.word owner:sarah https://webadaptorB.domain.com/arcgis admin password robert /
#!/usr/bin/env python
# Requires Python 2.7+
# Sample Usage:
# python copyContent.py <sourcePortal> <sourceAdmin> <sourcePassword>
#                       <query> <destinationPortal> <destAdmin>
#                       <destPassword> <destOwner> <destFolder>
import urllib
import json
import argparse
def generateToken(username, password, portalUrl):
    '''Retrieves a token to be used with API requests.'''
    parameters = urllib.urlencode({'username' : username,
                                   'password' : password,
                                   'client' : 'referer',
                                   'referer': portalUrl,
                                   'expiration': 60,
                                   'f' : 'json'})
    response = urllib.urlopen(portalUrl + '/sharing/rest/generateToken?',
                              parameters).read()
    try:
        jsonResponse = json.loads(response)
        if 'token' in jsonResponse:
            return jsonResponse['token']
        elif 'error' in jsonResponse:
            print jsonResponse['error']['message']
            for detail in jsonResponse['error']['details']:
                print detail
    except ValueError, e:
        print 'An unspecified error occurred.'
        print e
def searchPortal(portal, query=None, totalResults=None, sortField='numviews',
                 sortOrder='desc', token=None):
    '''
    Search the portal using the specified query and search parameters.
    Optionally provide a token to return results visible to that user.
    '''
    # Default results are returned by highest
    # number of views in descending order.
    allResults = []
    if not totalResults or totalResults > 100:
        numResults = 100
    else:
        numResults = totalResults
    results = __search__(portal, query, numResults, sortField, sortOrder, 0,
                         token)
    if not 'error' in results.keys():
        if not totalResults:
            totalResults = results['total'] # Return all of the results.
        allResults.extend(results['results'])
        while (results['nextStart'] > 0 and
               results['nextStart'] < totalResults):
            # Do some math to ensure it only
            # returns the total results requested.
            numResults = min(totalResults - results['nextStart'] + 1, 100)
            results = __search__(portal=portal, query=query,
                                 numResults=numResults, sortField=sortField,
                                 sortOrder=sortOrder, token=token,
                                 start=results['nextStart'])
            allResults.extend(results['results'])
        return allResults
    else:
        print results['error']['message']
        return results
def __search__(portal, query=None, numResults=100, sortField='numviews',
               sortOrder='desc', start=0, token=None):
    '''Retrieve a single page of search results.'''
    params = {
        'q': query,
        'num': numResults,
        'sortField': sortField,
        'sortOrder': sortOrder,
        'f': 'json',
        'start': start
    }
    if token:
        # Adding a token provides an authenticated search.
        params['token'] = token
    request = portal + '/sharing/rest/search?' + urllib.urlencode(params)
    results = json.loads(urllib.urlopen(request).read())
    return results
def getUserContent(username, portalUrl, token):
    ''''''
    parameters = urllib.urlencode({'token': token, 'f': 'json'})
    request = (portalUrl + '/sharing/rest/content/users/' + username +
               '?' + parameters)
    content = json.loads(urllib.urlopen(request).read())
    return content
def getItemDescription(itemId, portalUrl, token):
    '''Returns the description for a Portal for ArcGIS item.'''
    parameters = urllib.urlencode({'token' : token,
                                   'f' : 'json'})
    response = urllib.urlopen(portalUrl + "/sharing/rest/content/items/" +
                              itemId + "?" + parameters).read()
    return response
def getItemData(itemId, portalUrl, token):
    '''Returns the description for a Portal for ArcGIS item.'''
    parameters = urllib.urlencode({'token' : token,
                                   'f' : 'json'})
    response = urllib.urlopen(portalUrl + "/sharing/rest/content/items/" +
                              itemId + "/data?" + parameters).read()
    return response
def addItem(username, folder, description, data, portalUrl, token,
                thumbnailUrl=''):
    '''Creates a new item in a user's content.'''
    parameters = urllib.urlencode({'item': json.loads(description)['title'],
                                   'text': data,
                                   'overwrite': 'false',
                                   'thumbnailurl': thumbnailUrl,
                                   'token' : token,
                                   'f' : 'json'})
    postParameters = (urllib.urlencode(json.loads(description))
                      .replace('None', '') + '&' + parameters)
    response = urllib.urlopen(portalUrl + '/sharing/rest/content/users/' +
                              username + '/' + folder + '/addItem?',
                              postParameters).read()
    return response
def copyItem(itemId, destinationOwner, destinationFolder, sourcePortal,
             sourceToken, destinationPortal=None, destinationToken=None):
    '''
    Copies an item into a user's account in the specified folder.
    Use '/' as the destination folder when moving content into root.
    '''
    # This function defaults to copying into the same Portal
    # and with the same token permissions as the source account.
    # If the destination is a different Portal then specify that Portal url
    # and include a token with permissions on that instance.
    if not destinationPortal:
        destinationPortal = sourcePortal
    if not destinationToken:
        destinationToken = sourceToken
    description = getItemDescription(itemId, sourcePortal, sourceToken)
    data = getItemData(itemId, sourcePortal, sourceToken)
    thumbnail = json.loads(description)['thumbnail']
    if thumbnail:
        thumbnailUrl = (sourcePortal + '/sharing/rest/content/items/' +
                        itemId + '/info/' + thumbnail +
                        '?token=' + sourceToken)
    else:
        thumbnailUrl = ''
    status = addItem(destinationOwner, destinationFolder, description,
                         data, destinationPortal, destinationToken,
                         thumbnailUrl)
    return json.loads(status)
# Run the script.
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('sourcePortal',
                        help=('url of the source Portal (e.g. '
                              'https://portal.domain.com:7443/arcgis)'))
    parser.add_argument('sourceAdmin', help='source admin username')
    parser.add_argument('sourcePassword', help='source admin password')
    parser.add_argument("query", help='search string to find content')
    parser.add_argument('destPortal',
                        help=('url of the destination Portal (e.g. '
                              'https://portal.domain.com:7443/arcgis)'))
    parser.add_argument('destAdmin', help='destination admin username')
    parser.add_argument('destPassword', help='destination admin password')
    parser.add_argument('owner', help='destination account to copy to')
    parser.add_argument('folder', help='destination folder to copy to')
    # Read the command line arguments.
    args = parser.parse_args()
    sourcePortal = args.sourcePortal
    sourceAdmin = args.sourceAdmin
    sourcePassword = args.sourcePassword
    query = args.query
    destPortal = args.destPortal
    destAdmin = args.destAdmin
    destPassword = args.destPassword
    owner = args.owner
    folder = args.folder
    # Get a token for the source Portal for ArcGIS.
    sourceToken = generateToken(username=sourceAdmin, password=sourcePassword,
                          portalUrl=sourcePortal)
    # Get a token for the destination Portal for ArcGIS.
    destToken = generateToken(username=destAdmin, password=destPassword,
                              portalUrl=destPortal)
    # Get the destination folder ID.
    folderId = ''
    destUser = getUserContent(owner, destPortal, destToken)
    for folder in destUser['folders']:
        if folder['title'] == folder:
            folderId = folder['id']
    # Get a list of the content matching the query.
    content = searchPortal(portal=sourcePortal,
                           query=query,
                           token=sourceToken)
    # Copy the content into the destination user's account.
    for item in content:
        try:
            result = copyItem(item['id'], owner, folderId, sourcePortal,
                              sourceToken, destPortal, destToken)
            if 'success' in result:
                print 'successfully copied ' + item['type'] + ': ' + item['title']
            elif 'error' in result:
                print 'error copying ' + item['type'] + ': ' + item['title']
                print result['error']['message']
                for detail in result['error']['details']:
                    print detail
            else:
                print 'error copying ' + item['type'] + ': ' + item['title']
        except:
            'error copying ' + item['type'] + ': ' + item['title']
    print 'Copying complete.'