I'm trying to run this script against our federated Portal to add basemaps for offline. The only way I can seem to access our Portal (I've tested in jupyter notebook) without SSL errors thru python is if I include the "verify_cert=False" parameter.
Can someone please show me how to modify the "prepareEsriBasemapsForOfflineUse.py" python script such that the certificate errors are ignored? Like where exactly I should insert the "verify_cert=False" parameter below (python noob here). I seem to recall not having this problem on one of our older servers with this script, maybe one that wasn't https...
Thanks in advance!
IOError: [Errno socket error] [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:661)
<SPAN class="comment token">#!/usr/bin/env python</SPAN>
<SPAN class="comment token"># Requires Python 2.7+</SPAN>
<SPAN class="comment token"># Sample Usage:</SPAN>
<SPAN class="comment token"># python addOfflineBasemaps.py -u <destinationPortal> -o <portalAdmin></SPAN>
<SPAN class="comment token"># -s <portalPassword> -f <destFolder></SPAN>
<SPAN class="comment token"># -a <agoUsername> -p <agoPassword></SPAN>
<SPAN class="keyword token">import</SPAN> urllib
<SPAN class="keyword token">import</SPAN> json
<SPAN class="keyword token">import</SPAN> argparse
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">generateToken</SPAN><SPAN class="punctuation token">(</SPAN>username<SPAN class="punctuation token">,</SPAN> password<SPAN class="punctuation token">,</SPAN> portalUrl<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="string token">'''Retrieves a token to be used with API requests.'''</SPAN>
parameters <SPAN class="operator token">=</SPAN> urllib<SPAN class="punctuation token">.</SPAN>urlencode<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">{</SPAN><SPAN class="string token">'username'</SPAN> <SPAN class="punctuation token">:</SPAN> username<SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'password'</SPAN> <SPAN class="punctuation token">:</SPAN> password<SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'client'</SPAN> <SPAN class="punctuation token">:</SPAN> <SPAN class="string token">'referer'</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'referer'</SPAN><SPAN class="punctuation token">:</SPAN> portalUrl<SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'expiration'</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="number token">60</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'f'</SPAN> <SPAN class="punctuation token">:</SPAN> <SPAN class="string token">'json'</SPAN><SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN>
response <SPAN class="operator token">=</SPAN> urllib<SPAN class="punctuation token">.</SPAN>urlopen<SPAN class="punctuation token">(</SPAN>portalUrl <SPAN class="operator token">+</SPAN> <SPAN class="string token">'/sharing/rest/generateToken?'</SPAN><SPAN class="punctuation token">,</SPAN>
parameters<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>read<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">try</SPAN><SPAN class="punctuation token">:</SPAN>
jsonResponse <SPAN class="operator token">=</SPAN> json<SPAN class="punctuation token">.</SPAN>loads<SPAN class="punctuation token">(</SPAN>response<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">if</SPAN> <SPAN class="string token">'token'</SPAN> <SPAN class="keyword token">in</SPAN> jsonResponse<SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">return</SPAN> jsonResponse<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'token'</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">elif</SPAN> <SPAN class="string token">'error'</SPAN> <SPAN class="keyword token">in</SPAN> jsonResponse<SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">print</SPAN> jsonResponse<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'error'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'message'</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">for</SPAN> detail <SPAN class="keyword token">in</SPAN> jsonResponse<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'error'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'details'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">print</SPAN> detail
<SPAN class="keyword token">except</SPAN> ValueError<SPAN class="punctuation token">,</SPAN> e<SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">print</SPAN> <SPAN class="string token">'An unspecified error occurred.'</SPAN>
<SPAN class="keyword token">print</SPAN> e
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">searchPortal</SPAN><SPAN class="punctuation token">(</SPAN>portal<SPAN class="punctuation token">,</SPAN> query<SPAN class="operator token">=</SPAN>None<SPAN class="punctuation token">,</SPAN> totalResults<SPAN class="operator token">=</SPAN>None<SPAN class="punctuation token">,</SPAN> sortField<SPAN class="operator token">=</SPAN><SPAN class="string token">'numviews'</SPAN><SPAN class="punctuation token">,</SPAN>
sortOrder<SPAN class="operator token">=</SPAN><SPAN class="string token">'desc'</SPAN><SPAN class="punctuation token">,</SPAN> token<SPAN class="operator token">=</SPAN><SPAN class="string token">''</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="string token">'''
Search the portal using the specified query and search parameters.
Optionally provide a token to return results visible to that user.
'''</SPAN>
<SPAN class="comment token"># Default results are returned by highest</SPAN>
<SPAN class="comment token"># number of views in descending order.</SPAN>
allResults <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> totalResults <SPAN class="operator token">or</SPAN> totalResults <SPAN class="operator token">></SPAN> <SPAN class="number token">100</SPAN><SPAN class="punctuation token">:</SPAN>
numResults <SPAN class="operator token">=</SPAN> <SPAN class="number token">100</SPAN>
<SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN>
numResults <SPAN class="operator token">=</SPAN> totalResults
results <SPAN class="operator token">=</SPAN> __search__<SPAN class="punctuation token">(</SPAN>portal<SPAN class="punctuation token">,</SPAN> query<SPAN class="punctuation token">,</SPAN> numResults<SPAN class="punctuation token">,</SPAN> sortField<SPAN class="punctuation token">,</SPAN> sortOrder<SPAN class="punctuation token">,</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN>
token<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> <SPAN class="string token">'error'</SPAN> <SPAN class="keyword token">in</SPAN> results<SPAN class="punctuation token">.</SPAN>keys<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> totalResults<SPAN class="punctuation token">:</SPAN>
totalResults <SPAN class="operator token">=</SPAN> results<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'total'</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="comment token"># Return all of the results.</SPAN>
allResults<SPAN class="punctuation token">.</SPAN>extend<SPAN class="punctuation token">(</SPAN>results<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'results'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">while</SPAN> <SPAN class="punctuation token">(</SPAN>results<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'nextStart'</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">></SPAN> <SPAN class="number token">0</SPAN> <SPAN class="operator token">and</SPAN>
results<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'nextStart'</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token"><</SPAN> totalResults<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="comment token"># Do some math to ensure it only</SPAN>
<SPAN class="comment token"># returns the total results requested.</SPAN>
numResults <SPAN class="operator token">=</SPAN> min<SPAN class="punctuation token">(</SPAN>totalResults <SPAN class="operator token">-</SPAN> results<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'nextStart'</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="number token">1</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">100</SPAN><SPAN class="punctuation token">)</SPAN>
results <SPAN class="operator token">=</SPAN> __search__<SPAN class="punctuation token">(</SPAN>portal<SPAN class="operator token">=</SPAN>portal<SPAN class="punctuation token">,</SPAN> query<SPAN class="operator token">=</SPAN>query<SPAN class="punctuation token">,</SPAN>
numResults<SPAN class="operator token">=</SPAN>numResults<SPAN class="punctuation token">,</SPAN> sortField<SPAN class="operator token">=</SPAN>sortField<SPAN class="punctuation token">,</SPAN>
sortOrder<SPAN class="operator token">=</SPAN>sortOrder<SPAN class="punctuation token">,</SPAN> token<SPAN class="operator token">=</SPAN>token<SPAN class="punctuation token">,</SPAN>
start<SPAN class="operator token">=</SPAN>results<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'nextStart'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN>
allResults<SPAN class="punctuation token">.</SPAN>extend<SPAN class="punctuation token">(</SPAN>results<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'results'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN> allResults
<SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">print</SPAN> results<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'error'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'message'</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">return</SPAN> results
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">__search__</SPAN><SPAN class="punctuation token">(</SPAN>portal<SPAN class="punctuation token">,</SPAN> query<SPAN class="operator token">=</SPAN>None<SPAN class="punctuation token">,</SPAN> numResults<SPAN class="operator token">=</SPAN><SPAN class="number token">100</SPAN><SPAN class="punctuation token">,</SPAN> sortField<SPAN class="operator token">=</SPAN><SPAN class="string token">'numviews'</SPAN><SPAN class="punctuation token">,</SPAN>
sortOrder<SPAN class="operator token">=</SPAN><SPAN class="string token">'desc'</SPAN><SPAN class="punctuation token">,</SPAN> start<SPAN class="operator token">=</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN> token<SPAN class="operator token">=</SPAN>None<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="string token">'''Retrieve a single page of search results.'''</SPAN>
params <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">{</SPAN>
<SPAN class="string token">'q'</SPAN><SPAN class="punctuation token">:</SPAN> query<SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'num'</SPAN><SPAN class="punctuation token">:</SPAN> numResults<SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'sortField'</SPAN><SPAN class="punctuation token">:</SPAN> sortField<SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'sortOrder'</SPAN><SPAN class="punctuation token">:</SPAN> sortOrder<SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'f'</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">'json'</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'start'</SPAN><SPAN class="punctuation token">:</SPAN> start
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">if</SPAN> token<SPAN class="punctuation token">:</SPAN>
<SPAN class="comment token"># Adding a token provides an authenticated search.</SPAN>
params<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'token'</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">=</SPAN> token
request <SPAN class="operator token">=</SPAN> portal <SPAN class="operator token">+</SPAN> <SPAN class="string token">'/sharing/rest/search?'</SPAN> <SPAN class="operator token">+</SPAN> urllib<SPAN class="punctuation token">.</SPAN>urlencode<SPAN class="punctuation token">(</SPAN>params<SPAN class="punctuation token">)</SPAN>
results <SPAN class="operator token">=</SPAN> json<SPAN class="punctuation token">.</SPAN>loads<SPAN class="punctuation token">(</SPAN>urllib<SPAN class="punctuation token">.</SPAN>urlopen<SPAN class="punctuation token">(</SPAN>request<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>read<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN> results
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">groupSearch</SPAN><SPAN class="punctuation token">(</SPAN>query<SPAN class="punctuation token">,</SPAN> portalUrl<SPAN class="punctuation token">,</SPAN> token<SPAN class="operator token">=</SPAN><SPAN class="string token">''</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="string token">'''Search for groups matching the specified query.'''</SPAN>
<SPAN class="comment token"># Example 1: query all groups owned by a user.</SPAN>
<SPAN class="comment token"># 'owner:johndoe'</SPAN>
<SPAN class="comment token"># Example 2: query groups with Operations in the name.</SPAN>
<SPAN class="comment token"># 'Operations'</SPAN>
<SPAN class="comment token"># Example 3: query all groups with public access.</SPAN>
<SPAN class="comment token"># 'access:public'</SPAN>
parameters <SPAN class="operator token">=</SPAN> urllib<SPAN class="punctuation token">.</SPAN>urlencode<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">{</SPAN><SPAN class="string token">'q'</SPAN><SPAN class="punctuation token">:</SPAN> query<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">'token'</SPAN><SPAN class="punctuation token">:</SPAN> token<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">'f'</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">'json'</SPAN><SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN>
request <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>portalUrl <SPAN class="operator token">+</SPAN> <SPAN class="string token">'/sharing/rest/community/groups?'</SPAN> <SPAN class="operator token">+</SPAN> parameters<SPAN class="punctuation token">)</SPAN>
groups <SPAN class="operator token">=</SPAN> json<SPAN class="punctuation token">.</SPAN>loads<SPAN class="punctuation token">(</SPAN>urllib<SPAN class="punctuation token">.</SPAN>urlopen<SPAN class="punctuation token">(</SPAN>request<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>read<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN> groups<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'results'</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">getUserContent</SPAN><SPAN class="punctuation token">(</SPAN>username<SPAN class="punctuation token">,</SPAN> portalUrl<SPAN class="punctuation token">,</SPAN> token<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="string token">''''''
parameters = urllib.urlencode({'token': token, 'f': 'json'})
request = (portalUrl + '/sharing/rest/content/users/' + username +
'?' + parameters)
print request
content = urllib.urlopen(request).read()
return json.loads(content)
def getItemDescription(itemId, portalUrl, token=''):
'''</SPAN>Returns the description <SPAN class="keyword token">for</SPAN> a Portal <SPAN class="keyword token">for</SPAN> ArcGIS item<SPAN class="punctuation token">.</SPAN><SPAN class="string token">'''
parameters = urllib.urlencode({'token' : token,
'f' : 'json'})
response = urllib.urlopen(portalUrl + "/sharing/rest/content/items/" +
itemId + "?" + parameters).read()
return json.loads(unicode(response, 'utf-8'))
def createFolder(username, title, portalUrl, token):
'''</SPAN>Creates a new folder <SPAN class="keyword token">in</SPAN> a user<SPAN class="string token">'s content.'</SPAN><SPAN class="string token">''</SPAN>
parameters <SPAN class="operator token">=</SPAN> urllib<SPAN class="punctuation token">.</SPAN>urlencode<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">{</SPAN><SPAN class="string token">'title'</SPAN><SPAN class="punctuation token">:</SPAN> title<SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'token'</SPAN> <SPAN class="punctuation token">:</SPAN> token<SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'f'</SPAN> <SPAN class="punctuation token">:</SPAN> <SPAN class="string token">'json'</SPAN><SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN>
response <SPAN class="operator token">=</SPAN> urllib<SPAN class="punctuation token">.</SPAN>urlopen<SPAN class="punctuation token">(</SPAN>portalUrl <SPAN class="operator token">+</SPAN> <SPAN class="string token">'/sharing/rest/content/users/'</SPAN> <SPAN class="operator token">+</SPAN>
username <SPAN class="operator token">+</SPAN> <SPAN class="string token">'/createFolder?'</SPAN><SPAN class="punctuation token">,</SPAN> parameters<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>read<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN> json<SPAN class="punctuation token">.</SPAN>loads<SPAN class="punctuation token">(</SPAN>response<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">addServiceItem</SPAN><SPAN class="punctuation token">(</SPAN>username<SPAN class="punctuation token">,</SPAN> folder<SPAN class="punctuation token">,</SPAN> description<SPAN class="punctuation token">,</SPAN> serviceUrl<SPAN class="punctuation token">,</SPAN> portalUrl<SPAN class="punctuation token">,</SPAN>
token<SPAN class="punctuation token">,</SPAN> thumbnailUrl<SPAN class="operator token">=</SPAN><SPAN class="string token">''</SPAN><SPAN class="punctuation token">,</SPAN> serviceUsername<SPAN class="operator token">=</SPAN>None<SPAN class="punctuation token">,</SPAN>
servicePassword<SPAN class="operator token">=</SPAN>None<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="string token">'''Creates a new item in a user's content.'''</SPAN>
<SPAN class="comment token"># Update the description with unicode safe values.</SPAN>
descriptionJSON <SPAN class="operator token">=</SPAN> __decodeDict__<SPAN class="punctuation token">(</SPAN>json<SPAN class="punctuation token">.</SPAN>loads<SPAN class="punctuation token">(</SPAN>description<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
parameters <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">{</SPAN><SPAN class="string token">'item'</SPAN><SPAN class="punctuation token">:</SPAN> descriptionJSON<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'title'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'url'</SPAN><SPAN class="punctuation token">:</SPAN> serviceUrl<SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'thumbnailurl'</SPAN><SPAN class="punctuation token">:</SPAN> thumbnailUrl<SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'overwrite'</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">'false'</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'token'</SPAN> <SPAN class="punctuation token">:</SPAN> token<SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'f'</SPAN> <SPAN class="punctuation token">:</SPAN> <SPAN class="string token">'json'</SPAN><SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">if</SPAN> serviceUsername <SPAN class="operator token">and</SPAN> servicePassword<SPAN class="punctuation token">:</SPAN>
<SPAN class="comment token"># Store the credentials with the service.</SPAN>
parameters<SPAN class="punctuation token">.</SPAN>update<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">{</SPAN><SPAN class="string token">'serviceUsername'</SPAN><SPAN class="punctuation token">:</SPAN> serviceUsername<SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'servicePassword'</SPAN><SPAN class="punctuation token">:</SPAN> servicePassword<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token"># Add the item's description (with safe values for unicode).</SPAN>
parameters<SPAN class="punctuation token">.</SPAN>update<SPAN class="punctuation token">(</SPAN>descriptionJSON<SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token"># Encode and post the item.</SPAN>
postParameters <SPAN class="operator token">=</SPAN> urllib<SPAN class="punctuation token">.</SPAN>urlencode<SPAN class="punctuation token">(</SPAN>parameters<SPAN class="punctuation token">)</SPAN>
response <SPAN class="operator token">=</SPAN> urllib<SPAN class="punctuation token">.</SPAN>urlopen<SPAN class="punctuation token">(</SPAN>portalUrl <SPAN class="operator token">+</SPAN> <SPAN class="string token">'/sharing/rest/content/users/'</SPAN> <SPAN class="operator token">+</SPAN>
username <SPAN class="operator token">+</SPAN> <SPAN class="string token">'/'</SPAN> <SPAN class="operator token">+</SPAN> folder <SPAN class="operator token">+</SPAN> <SPAN class="string token">'/addItem?'</SPAN><SPAN class="punctuation token">,</SPAN>
postParameters<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>read<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN> json<SPAN class="punctuation token">.</SPAN>loads<SPAN class="punctuation token">(</SPAN>response<SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token"># Helper functions for decoding the unicode values in the response json.</SPAN>
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">__decodeDict__</SPAN><SPAN class="punctuation token">(</SPAN>dct<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
newdict <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">{</SPAN><SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">for</SPAN> k<SPAN class="punctuation token">,</SPAN> v <SPAN class="keyword token">in</SPAN> dct<SPAN class="punctuation token">.</SPAN>iteritems<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
k <SPAN class="operator token">=</SPAN> __safeValue__<SPAN class="punctuation token">(</SPAN>k<SPAN class="punctuation token">)</SPAN>
v <SPAN class="operator token">=</SPAN> __safeValue__<SPAN class="punctuation token">(</SPAN>v<SPAN class="punctuation token">)</SPAN>
newdict<SPAN class="punctuation token">[</SPAN>k<SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">=</SPAN> v
<SPAN class="keyword token">return</SPAN> newdict
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">__safeValue__</SPAN><SPAN class="punctuation token">(</SPAN>inVal<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
outVal <SPAN class="operator token">=</SPAN> inVal
<SPAN class="keyword token">if</SPAN> isinstance<SPAN class="punctuation token">(</SPAN>inVal<SPAN class="punctuation token">,</SPAN> unicode<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
outVal <SPAN class="operator token">=</SPAN> inVal<SPAN class="punctuation token">.</SPAN>encode<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'utf-8'</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">elif</SPAN> isinstance<SPAN class="punctuation token">(</SPAN>inVal<SPAN class="punctuation token">,</SPAN> list<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
outVal <SPAN class="operator token">=</SPAN> __decode_list__<SPAN class="punctuation token">(</SPAN>inVal<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN> outVal
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">__decode_list__</SPAN><SPAN class="punctuation token">(</SPAN>lst<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
newList <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">for</SPAN> i <SPAN class="keyword token">in</SPAN> lst<SPAN class="punctuation token">:</SPAN>
i <SPAN class="operator token">=</SPAN> __safeValue__<SPAN class="punctuation token">(</SPAN>i<SPAN class="punctuation token">)</SPAN>
newList<SPAN class="punctuation token">.</SPAN>append<SPAN class="punctuation token">(</SPAN>i<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">return</SPAN> newList
<SPAN class="comment token"># Run the script.</SPAN>
<SPAN class="keyword token">if</SPAN> __name__ <SPAN class="operator token">==</SPAN> <SPAN class="string token">'__main__'</SPAN><SPAN class="punctuation token">:</SPAN>
parser <SPAN class="operator token">=</SPAN> argparse<SPAN class="punctuation token">.</SPAN>ArgumentParser<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
parser<SPAN class="punctuation token">.</SPAN>add_argument<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'-u'</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">'--portal'</SPAN><SPAN class="punctuation token">,</SPAN> required<SPAN class="operator token">=</SPAN><SPAN class="token boolean">True</SPAN><SPAN class="punctuation token">,</SPAN>
help<SPAN class="operator token">=</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">'url of the Portal (e.g. '</SPAN>
<SPAN class="string token"><SPAN>'</SPAN><A class="jive-link-external-small" href="https://community.esri.com/external-link.jspa?url=https%3A%2F%2Fportal.domain.com%3A7443%2Farcgis" target="_blank">https://portal.domain.com:7443/arcgis</A><SPAN>)'</SPAN></SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
parser<SPAN class="punctuation token">.</SPAN>add_argument<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'-o'</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">'--portalAdmin'</SPAN><SPAN class="punctuation token">,</SPAN> required<SPAN class="operator token">=</SPAN><SPAN class="token boolean">True</SPAN><SPAN class="punctuation token">,</SPAN>
help<SPAN class="operator token">=</SPAN><SPAN class="string token">'Portal admin username'</SPAN><SPAN class="punctuation token">)</SPAN>
parser<SPAN class="punctuation token">.</SPAN>add_argument<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'-s'</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">'--portalPassword'</SPAN><SPAN class="punctuation token">,</SPAN> required<SPAN class="operator token">=</SPAN><SPAN class="token boolean">True</SPAN><SPAN class="punctuation token">,</SPAN>
help<SPAN class="operator token">=</SPAN><SPAN class="string token">'Portal admin password'</SPAN><SPAN class="punctuation token">)</SPAN>
parser<SPAN class="punctuation token">.</SPAN>add_argument<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'-a'</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">'--agoAdmin'</SPAN><SPAN class="punctuation token">,</SPAN> required<SPAN class="operator token">=</SPAN><SPAN class="token boolean">True</SPAN><SPAN class="punctuation token">,</SPAN>
help<SPAN class="operator token">=</SPAN><SPAN class="string token">'ArcGIS Online admin username'</SPAN><SPAN class="punctuation token">)</SPAN>
parser<SPAN class="punctuation token">.</SPAN>add_argument<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'-p'</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">'--agoPassword'</SPAN><SPAN class="punctuation token">,</SPAN> required<SPAN class="operator token">=</SPAN><SPAN class="token boolean">True</SPAN><SPAN class="punctuation token">,</SPAN>
help<SPAN class="operator token">=</SPAN><SPAN class="string token">'ArcGIS Online admin password'</SPAN><SPAN class="punctuation token">)</SPAN>
parser<SPAN class="punctuation token">.</SPAN>add_argument<SPAN class="punctuation token">(</SPAN><SPAN class="string token">'-f'</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">'--folder'</SPAN><SPAN class="punctuation token">,</SPAN> required<SPAN class="operator token">=</SPAN><SPAN class="token boolean">False</SPAN><SPAN class="punctuation token">,</SPAN>
help<SPAN class="operator token">=</SPAN><SPAN class="string token">'Optional destination folder'</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token"># Read the command line arguments.</SPAN>
args <SPAN class="operator token">=</SPAN> parser<SPAN class="punctuation token">.</SPAN>parse_args<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
agoAdmin <SPAN class="operator token">=</SPAN> args<SPAN class="punctuation token">.</SPAN>agoAdmin
agoPassword <SPAN class="operator token">=</SPAN> args<SPAN class="punctuation token">.</SPAN>agoPassword
portal <SPAN class="operator token">=</SPAN> args<SPAN class="punctuation token">.</SPAN>portal
portalAdmin <SPAN class="operator token">=</SPAN> args<SPAN class="punctuation token">.</SPAN>portalAdmin
portalPassword <SPAN class="operator token">=</SPAN> args<SPAN class="punctuation token">.</SPAN>portalPassword
folderTitle <SPAN class="operator token">=</SPAN> args<SPAN class="punctuation token">.</SPAN>folder
<SPAN class="comment token"># Get a token for the Portal for ArcGIS.</SPAN>
<SPAN class="keyword token">print</SPAN> <SPAN class="string token">'Getting token for '</SPAN> <SPAN class="operator token">+</SPAN> portal
token <SPAN class="operator token">=</SPAN> generateToken<SPAN class="punctuation token">(</SPAN>username<SPAN class="operator token">=</SPAN>portalAdmin<SPAN class="punctuation token">,</SPAN> password<SPAN class="operator token">=</SPAN>portalPassword<SPAN class="punctuation token">,</SPAN>
portalUrl<SPAN class="operator token">=</SPAN>portal<SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token"># Get the destination folder ID.</SPAN>
folderId <SPAN class="operator token">=</SPAN> <SPAN class="string token">''</SPAN>
<SPAN class="keyword token">if</SPAN> folderTitle <SPAN class="operator token">==</SPAN> None<SPAN class="punctuation token">:</SPAN>
<SPAN class="comment token"># No folder specified. Folder is root.</SPAN>
<SPAN class="keyword token">print</SPAN> <SPAN class="string token">'Using the root folder...'</SPAN>
folderId <SPAN class="operator token">=</SPAN> <SPAN class="string token">'/'</SPAN>
<SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="comment token"># Check if the folder already exists.</SPAN>
userContent <SPAN class="operator token">=</SPAN> getUserContent<SPAN class="punctuation token">(</SPAN>portalAdmin<SPAN class="punctuation token">,</SPAN> portal<SPAN class="punctuation token">,</SPAN> token<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">for</SPAN> folder <SPAN class="keyword token">in</SPAN> userContent<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'folders'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">if</SPAN> folder<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'title'</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">==</SPAN> folderTitle<SPAN class="punctuation token">:</SPAN>
folderId <SPAN class="operator token">=</SPAN> folder<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'id'</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="comment token"># Create the folder if it was not found.</SPAN>
<SPAN class="keyword token">if</SPAN> folderId <SPAN class="operator token">==</SPAN> <SPAN class="string token">''</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">print</SPAN> <SPAN class="string token">'Creating folder '</SPAN> <SPAN class="operator token">+</SPAN> args<SPAN class="punctuation token">.</SPAN>folder <SPAN class="operator token">+</SPAN> <SPAN class="string token">'...'</SPAN>
newFolder <SPAN class="operator token">=</SPAN> createFolder<SPAN class="punctuation token">(</SPAN>portalAdmin<SPAN class="punctuation token">,</SPAN> folderTitle<SPAN class="punctuation token">,</SPAN> portal<SPAN class="punctuation token">,</SPAN> token<SPAN class="punctuation token">)</SPAN>
folderId <SPAN class="operator token">=</SPAN> newFolder<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'folder'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'id'</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">print</SPAN> <SPAN class="string token">'Using folder '</SPAN> <SPAN class="operator token">+</SPAN> folderTitle <SPAN class="operator token">+</SPAN> <SPAN class="string token">' (id:'</SPAN> <SPAN class="operator token">+</SPAN> folderId <SPAN class="operator token">+</SPAN> <SPAN class="string token">')'</SPAN>
<SPAN class="comment token"># Get the ArcGIS Online group ID.</SPAN>
query <SPAN class="operator token">=</SPAN> <SPAN class="string token">'owner:esri title:Tiled Basemaps'</SPAN>
<SPAN class="comment token"># Search for the public ArcGIS Online group (no token needed).</SPAN>
sourceGroup <SPAN class="operator token">=</SPAN> groupSearch<SPAN class="punctuation token">(</SPAN>query<SPAN class="punctuation token">,</SPAN> <SPAN class="string token"><SPAN>'</SPAN><A class="jive-link-external-small" href="https://community.esri.com/external-link.jspa?url=https%3A%2F%2Fwww.arcgis.com" target="_blank">https://www.arcgis.com</A><SPAN>'</SPAN></SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'id'</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="comment token"># Get the items in the ArcGIS Online group specified above.</SPAN>
basemaps <SPAN class="operator token">=</SPAN> searchPortal<SPAN class="punctuation token">(</SPAN><SPAN class="string token"><SPAN>'</SPAN><A class="jive-link-external-small" href="https://community.esri.com/external-link.jspa?url=https%3A%2F%2Fwww.arcgis.com" target="_blank">https://www.arcgis.com</A><SPAN>'</SPAN></SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">'group:'</SPAN> <SPAN class="operator token">+</SPAN> sourceGroup<SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token"># Add the basemaps as new items in the Portal.</SPAN>
<SPAN class="keyword token">for</SPAN> basemap <SPAN class="keyword token">in</SPAN> basemaps<SPAN class="punctuation token">:</SPAN>
<SPAN class="comment token"># Get the item description.</SPAN>
description <SPAN class="operator token">=</SPAN> getItemDescription<SPAN class="punctuation token">(</SPAN>basemap<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'id'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token"><SPAN>'</SPAN><A class="jive-link-external-small" href="https://community.esri.com/external-link.jspa?url=https%3A%2F%2Fwww.arcgis.com" target="_blank">https://www.arcgis.com</A><SPAN>'</SPAN></SPAN><SPAN class="punctuation token">)</SPAN>
serviceUrl <SPAN class="operator token">=</SPAN> description<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'url'</SPAN><SPAN class="punctuation token">]</SPAN>
thumbUrl <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token"><SPAN>'</SPAN><A class="jive-link-external-small" href="https://community.esri.com/external-link.jspa?url=https%3A%2F%2Fwww.arcgis.com" target="_blank">https://www.arcgis.com</A><SPAN>'</SPAN></SPAN> <SPAN class="operator token">+</SPAN>
<SPAN class="string token">'/sharing/rest/content/items/'</SPAN> <SPAN class="operator token">+</SPAN> description<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'id'</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">+</SPAN>
<SPAN class="string token">'/info/'</SPAN> <SPAN class="operator token">+</SPAN> description<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'thumbnail'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN>
newDescription <SPAN class="operator token">=</SPAN> json<SPAN class="punctuation token">.</SPAN>dumps<SPAN class="punctuation token">(</SPAN>
<SPAN class="punctuation token">{</SPAN><SPAN class="string token">'title'</SPAN><SPAN class="punctuation token">:</SPAN> description<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'title'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'type'</SPAN><SPAN class="punctuation token">:</SPAN> description<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'type'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'snippet'</SPAN><SPAN class="punctuation token">:</SPAN> description<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'snippet'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'description'</SPAN><SPAN class="punctuation token">:</SPAN> description<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'description'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'licenseInfo'</SPAN><SPAN class="punctuation token">:</SPAN> description<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'licenseInfo'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'tags'</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">','</SPAN><SPAN class="punctuation token">.</SPAN>join<SPAN class="punctuation token">(</SPAN>description<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'tags'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'typeKeywords'</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">','</SPAN><SPAN class="punctuation token">.</SPAN>join<SPAN class="punctuation token">(</SPAN>description<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'typeKeywords'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'accessInformation'</SPAN><SPAN class="punctuation token">:</SPAN> description<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'accessInformation'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">try</SPAN><SPAN class="punctuation token">:</SPAN>
result <SPAN class="operator token">=</SPAN> addServiceItem<SPAN class="punctuation token">(</SPAN>portalAdmin<SPAN class="punctuation token">,</SPAN> folderId<SPAN class="punctuation token">,</SPAN> newDescription<SPAN class="punctuation token">,</SPAN>
serviceUrl<SPAN class="punctuation token">,</SPAN> portal<SPAN class="punctuation token">,</SPAN> token<SPAN class="punctuation token">,</SPAN> thumbUrl<SPAN class="punctuation token">,</SPAN>
agoAdmin<SPAN class="punctuation token">,</SPAN> agoPassword<SPAN class="punctuation token">)</SPAN>
<SPAN class="keyword token">if</SPAN> <SPAN class="string token">'success'</SPAN> <SPAN class="keyword token">in</SPAN> result<SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">print</SPAN> <SPAN class="string token">'Successfully added '</SPAN> <SPAN class="operator token">+</SPAN> basemap<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'title'</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">elif</SPAN> <SPAN class="string token">'error'</SPAN> <SPAN class="keyword token">in</SPAN> result<SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">print</SPAN> <SPAN class="string token">'Error copying '</SPAN> <SPAN class="operator token">+</SPAN> basemap<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'title'</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">print</SPAN> result<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'error'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'message'</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">for</SPAN> detail <SPAN class="keyword token">in</SPAN> result<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'error'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">'details'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">print</SPAN> detail
<SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">print</SPAN> <SPAN class="string token">'Error copying '</SPAN> <SPAN class="operator token">+</SPAN> basemap<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'title'</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">print</SPAN> <SPAN class="string token">'An unhandled error occurred.'</SPAN>
<SPAN class="keyword token">except</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="keyword token">print</SPAN> <SPAN class="string token">'Error copying '</SPAN> <SPAN class="operator token">+</SPAN> basemap<SPAN class="punctuation token">[</SPAN><SPAN class="string token">'title'</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="keyword token">print</SPAN> <SPAN class="string token">'An unhandled exception occurred.'</SPAN>
<SPAN class="keyword token">print</SPAN> <SPAN class="string token">'Copying complete.'</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>