해당 예시에서는 한 포털 (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.'