Ejemplo: Copia de contenido
En este ejemplo se copia todo el contenido propiedad de un miembro de un portal (A) a otro portal (B). La propiedad del contenido en el portal A se transfiere a la cuenta especificada en el portal B. Esto resulta útil en organizaciones que tengan dos portales. Por ejemplo, uno para uso interno y otro para uso externo, o una organización que tenga un entorno de desarrollo y otro de producción. Esta secuencia de comandos también se puede usar para mover contenido de Portal for ArcGIS a ArcGIS Online y viceversa.
Debe especificar la siguiente información cuando ejecute la secuencia de comandos:
- La URL usada para acceder al primer portal (A). Puede ser la URL de ArcGIS Web Adaptor, por ejemplo, https://webadaptorA.domain.com/arcgis o la URL de la máquina que aloja el portal, por ejemplo, https://portalA.domain.com:7443/arcgis. Debe incluir el nombre de dominio completo del equipo cuando especifique la URL.
- El nombre de usuario y la contraseña de una cuenta que tenga privilegios administrativos en el portal A.
- El nombre de usuario de la cuenta propietaria del contenido que se copiará del portal A al portal B, por ejemplo, sarah.
- La URL usada para acceder al segundo portal (B). Puede ser la URL de ArcGIS Web Adaptor, por ejemplo, https://webadaptorB.domain.com/arcgis o la URL de la máquina que aloja el portal, por ejemplo, https://portalB.domain.com:7443/arcgis. Debe incluir el nombre de dominio completo del equipo cuando especifique la URL.
- El nombre de usuario y la contraseña de una cuenta que tenga privilegios administrativos en el portal B.
- El nombre de usuario de la cuenta que será propietaria del contenido que se copiará del portal (A) al portal (B), por ejemplo, robert.
- La carpeta de miembro en el portal B donde se copiará el contenido. Esta ubicación es siempre la carpeta raíz (/). El contenido no puede copiarse en ninguna subcarpeta dentro de la carpeta raíz.
En el siguiente ejemplo se copia todo el contenido propiedad del miembro sarah del portal A en el miembro robert del portal B:
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.'