-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathArcGIS_GroupAs_ISO19650_CDE.py
356 lines (322 loc) · 20.6 KB
/
ArcGIS_GroupAs_ISO19650_CDE.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
import requests
import json
# ISO categories structure
IsoCategories = [{'title': 'Categories',
'categories': [
{'title': 'WIP', 'categories': [
{'title': 'S0', 'categories': []}]},
{'title': 'Shared (non-contractual)', 'categories': [
{'title': 'S1 - Suitable for coordination', 'categories': []},
{'title': 'S2 - Suitable for information', 'categories': []},
{'title': 'S3 - Suitable for review and comment', 'categories': []},
{'title': 'S4 - Suitable for stage approval', 'categories': []},
{'title': 'S6 - Suitable for PIM authorization', 'categories': []},
{'title': 'S7 - Suitable for AIM authorization', 'categories': []}]},
{'title': 'Published (contractual)', 'categories': [
{'title': 'A1 - Accepted stage 1', 'categories': []},
{'title': 'A2 - Accepted stage 2', 'categories': []},
{'title': 'A3 - Accepted stage 3', 'categories': []},
{'title': 'A4 - Accepted stage 4', 'categories': []},
{'title': 'A5 - Accepted stage 5', 'categories': []},
{'title': 'A6 - Accepted stage 6', 'categories': []}]},
{'title': 'Archive', 'categories': []},
{'title': 'Reference data', 'categories': []}]}]
# generate token function can be used once to get a token of your portal using rest api.
def generateToken(username, password, portalUrl):
headers = {'content-type': 'application/x-www-form-urlencoded', 'Host': 'www.arcgis.com', 'Content-Length': '[]' }
parameters = {'username': username,
'password': password,
'client': 'referer',
'referer': portalUrl,
'expiration': '60',
'f': 'json'}
url = portalUrl + '/sharing/rest/generateToken?'
response = requests.post(url, data=parameters, headers=headers)
try:
jsonResponse = response.json()
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:
print('An unspecified error occurred.')
print(ValueError)
# assignin ISO using REST API in python
def assignISO19650StatesAndStatusRESTapi(AuthenticationToken , group,
categories= IsoCategories, portal_URL = r"https://www.arcgis.com"):
Rest_API_Parameter = {"categorySchema": categories}
Parameter = {"categorySchema": json.dumps(Rest_API_Parameter)}
Parameter['token'] = AuthenticationToken
url = portal_URL + r"/sharing/rest/community/groups/" + group + "/assignCategorySchema?f=json"
response = requests.post(url, params= Parameter)
try:
jsonResponse = response.json()
if 'success' in jsonResponse:
return jsonResponse['success']
elif 'error' in jsonResponse:
print (jsonResponse['error']['message'])
for detail in jsonResponse['error']['details']:
print (detail)
except ValueError:
print('An unspecified error occurred. \nValueError')
# assign state and status to an Item in a group!
def updateItemsCategoriesOfGroup(AuthenticationToken , group, itemid, state = None , status =None , portal_URL = r"https://www.arcgis.com", isoStateStatus = IsoCategories):
def CheckStateStatusValidity(Ste,stus, isoStateStatus ):
for i in isoStateStatus[0]['categories']:
if i["title"] == Ste:
if stus != None:
for j in i["categories"]:
if j["title"] == stus:
return True
else: return True
return
if state != None:
itemsID_Categories = [{itemid: ["/Categories/"+ state]}]
else:
print("Error: provide a state")
return
if status != None:
itemsID_Categories[0][itemid][0] += "/" + status
if CheckStateStatusValidity (state, status,isoStateStatus ):
Parameter = {'items': json.dumps(itemsID_Categories)}
Parameter['token'] = AuthenticationToken
url = portal_URL + r"/sharing/rest/content/groups/" + group + "/updateCategories?f=json"
response = requests.post(url, params= Parameter)
try:
jsonResponse = response.json()
if 'results' in jsonResponse:
if status == None: status = ""
else:status = "and status " + "\"" + status + "\""
print ("Item " + jsonResponse['results'][0]['itemId'] + f" has been updated with state \"{state}\" {status}")
return True
elif 'error' in jsonResponse:
print (jsonResponse['error']['message'], " ", jsonResponse['error']['details'] )
return
except ValueError:
print('An unspecified error occurred. \nValueError')
return
print ("State and/or status of the item are not valid")
return
# update the snippet/description with metadata
def update_Snippet_Or_Description_SRC(AuthenticationToken, itemid, userName, tags = None, SRC = "Revision: P.00.00, Approved: True, Last updated by: UserName, Container classification: Not defined",
SnippetOrDescription = "snippet", portal_URL = r"https://www.arcgis.com" ):
Parameter = {SnippetOrDescription: SRC}
Parameter['token'] = AuthenticationToken
# Parameter['tags'] = "Shared (non-contractual),Published (contractual)"
if tags:
if len (tags) ==1:
tagsString = tags[0]
Parameter['tags'] = tagsString
elif len (tags) >1:
tagsString = tags[0]
for tag in tags[1:]:
tagsString = tagsString + "," + tag
Parameter['tags'] = tagsString
url = portal_URL + "/sharing/rest/content/users/" + userName + "/items/" + itemid + "/update?f=json"
response = requests.post(url, params= Parameter)
try:
jsonResponse = response.json()
if 'success' in jsonResponse:
return jsonResponse['success']
except ValueError:
print('An unspecified error occurred. \nValueError')
# update the revision in the meta data based on the state assigned to it (the current one and the next one)
def updateRevision (CurrectState, NextState, revision, categories = IsoCategories):
WIPrevision = int (revision[-2:])
sharedRevison = int (revision[-5:-3])
if NextState == categories[0]['categories'][0]['title']: #WIP
if CurrectState == categories[0]['categories'][0]['title']: # WIP
return revision[:-5] + str (f"{sharedRevison:02}") + "." + str (f"{WIPrevision+1:02}")
else:
return revision[:-5] + str (f"{sharedRevison:02}") + "." + str(f"{0:02}")
elif NextState == categories[0]['categories'][1]['title']: # Shared
return revision[:-5] + str (f"{sharedRevison+1:02}") + "." + str (f"{0:02}")
elif NextState == categories[0]['categories'][2]['title']: # Published
if revision[-7:-5] == "C.": return revision[:-5] + str (f"{sharedRevison+1:02}") + "." + str (f"{0:02}")
return revision[:-7] + "C." + str (f"{1:02}") + "." + str (f"{0:02}")
else:
print ("Error: revision function works only between WIP, Shared and Published environment.\nCheck revision structure in the metadata it should be something like \"Revision: P.00.00\"" )
return revision
# list all items in a group return a list of items (note this is different from the info of an item itself even tho there are many common attributes)
# so you can see the returned info as item details for arranging the items inside a group
def list_ItemsInGroup(AuthenticationToken, groupid, portal_URL = r"https://www.arcgis.com"):
Parameter = {'token': AuthenticationToken}
url = portal_URL + r"/sharing/rest/content/groups/" + groupid + "?f=json"
response = requests.post(url, params= Parameter)
try:
jsonResponse = response.json()
if 'total' in jsonResponse:
if jsonResponse["total"] > 0:
return jsonResponse ['items']
else: return
except ValueError:
print('An unspecified error occurred. \nValueError')
# this function adds a comment to an item
def addComment(AuthenticationToken, itemid, Comment = "No comment provided", portal_URL = r"https://www.arcgis.com"):
Parameter = {'token': AuthenticationToken, 'Comment': Comment}
url = portal_URL + r"/sharing/rest/content/items/" + itemid + "/addComment?f=json"
response = requests.post(url, params= Parameter)
jsonResponse = response.json()
try:
if 'success' in jsonResponse:
return jsonResponse['success'], jsonResponse['commentId']
except ValueError:
print('An unspecified error occurred. \nValueError')
def approve(AuthenticationToken, itemid, userName, portal_URLApprove = r"https://www.arcgis.com"):
metadata = getItemMetadataAndTags(AuthenticationToken, itemid, snippetOrdisc = "snippet", portal_URL = portal_URLApprove)[0]
revision, approved, lastUpdate, containerClass = metadata.split(",")
if "False" in approved.split(":")[1]:
approved = " Approved: True"
SRCReturned = revision + "," + approved + "," + lastUpdate + "," + containerClass
commentUsser = input("Add a comment: ...")
if commentUsser == "": commentUsser = "No comment"
commentUsser = "Approved by" + userName + ":" + commentUsser
addComment(AuthenticationToken, itemid, commentUsser, portal_URLApprove)
return update_Snippet_Or_Description_SRC(AuthenticationToken, itemid, userName, tags=None, SRC=SRCReturned, portal_URL=portal_URLApprove )
elif "True" in approved.split(":")[1]:
print ("Information container is already approved")
return
else:
print ("Error: something went wrong, check on the metadata")
return
# create a group or update an existing one with states and status of ISO 19650 standards/ return True / error
def CreateISO19650Based_Group(AuthenticationToken, titleOritemID,
description = "group for managing ISO 19650 workflows", Categories =IsoCategories,
portal_URL = r"https://www.arcgis.com" ):
url = portal_URL + "/sharing/rest/community/createGroup?f=json"
Parameter = {"title": titleOritemID, 'token':AuthenticationToken, 'description': description, "access":"account"}
response = requests.post(url, params= Parameter)
JsonResponse = response.json()
try:
if 'success' in JsonResponse:
return assignISO19650StatesAndStatusRESTapi (AuthenticationToken, JsonResponse['group']['id'], Categories)
else:
if 'error' in JsonResponse:
print (JsonResponse['error']['message'],"\n",JsonResponse['error']['details'][0] )
except ValueError:
print('An unspecified error occurred. \nValueError')
# function that return metadata from Snippet and tags of an item
def getItemMetadataAndTags(AuthenticationToken, itemid, snippetOrdisc = "snippet", portal_URL = r"https://www.arcgis.com"):
Parameter = {'token': AuthenticationToken}
url = portal_URL + r"/sharing/rest/content/items/" + itemid + "?f=json"
response = requests.post(url, params= Parameter)
try:
jsonResponse = response.json()
# print (jsonResponse)
if snippetOrdisc in jsonResponse:
return jsonResponse[snippetOrdisc], jsonResponse['tags']
elif 'error'in jsonResponse:
return jsonResponse
except ValueError:
print('An unspecified error occurred. \nValueError')
# return the state (category) of an item - True (if WIP, shared or published) / False (if other states e.g archive), None if state does not exist.
def getItemsState(AuthenticationToken, itemid, groupid, portal_URL = r"https://www.arcgis.com", categories = IsoCategories):
itemsIngroug = list_ItemsInGroup(AuthenticationToken, groupid, portal_URL)
for item in itemsIngroug:
if item['id']== itemid:
if len(item['groupCategories']) ==1:
state = item['groupCategories'][0].split("/")[2]
if state == categories[0]['categories'][0]['title'] or state == categories[0]['categories'][1]['title'] or state == categories[0]['categories'][2]['title']:return True, state
elif state == categories[0]['categories'][3]['title'] or state == categories[0]['categories'][4]['title']: return False, state
else:
print (f"Error: item is not assigned one of the states specified {categories[0]['categories'][0]['title'], categories[0]['categories'][1]['title'], categories[0]['categories'][2]['title']}")
return False, None
return False, None
# takes a as in put current state, next state and the list of the tags of the incident item, it reurns a list of the updated tags accordingly
def updateTags(current, next_, tagsList_, categories = IsoCategories):
for tag in tagsList_:
if current != tag:
if tag in [categories[0]['categories'][0]['title'], categories[0]['categories'][1]['title'], categories[0]['categories'][2]['title']]:
tagsList_.remove(tag)
counter = 0
for tag2 in tagsList_:
if current == tag2:
tagsList_[counter] = next_
return tagsList_
counter += 1
if next_ in [categories[0]['categories'][0]['title'], categories[0]['categories'][1]['title'], categories[0]['categories'][2]['title']]:
tagsList_.append(next_)
print ("Tags has no tag of the current state")
return tagsList_
# main Push functionalities that is used to transition items between ISO 19650 states (WIP, shared, published)
# It updates the metadata of an item (information container) such as revision,
# if approved of the metadata true it becomes False
def push (AuthenticationToken, itemid, groupid, userName, NextState, statusPush =None,
categories = IsoCategories, snippetOrDisc = "snippet", portal_URL= r"https://www.arcgis.com"):
def checkStateStatusValidityPush(stateCheck, statusCheck, categories2 = categories):
# checks if status and state of the information container (item) are valid for the push function
for i in categories2[0]['categories'][:3]:
if i["title"] == stateCheck:
if statusCheck != None:
for j in i["categories"]:
if j["title"] == statusCheck:
return True
else: return True
# check the validity of the state and status provided by the user
if checkStateStatusValidityPush(NextState, statusPush, categories):
# Getting the current state of an item and check its validity for push function
TrOrFa, CurrectState = getItemsState(AuthenticationToken, itemid, groupid)
if TrOrFa: metadata, tagsList = getItemMetadataAndTags(AuthenticationToken, itemid)
else:
print("Error: Item has invalid state\nWarning: push function works only between WIP, shared, and published states\nConsider initializing metadata using initilizemetadataOfitem() function")
# update tags list with the next state / return updated list
tagsL = updateTags(CurrectState, NextState, tagsList)
# devide the metadata into parameters to be updated and check the structure
parameters = len (metadata.split(","))
if parameters == 3:
revision, Approved, lastUpdate = metadata.split(",")
if "Revision:" not in revision or "Approved:" not in Approved or "Last updated by" not in lastUpdate:
print ("structure of the metadata in snippet is wrong")
return
elif parameters == 4:
revision, Approved, lastUpdate, containerClass = metadata.split(",")
if "Revision:" not in revision or "Approved:" not in Approved or "Last updated by:" not in lastUpdate or "Container classification:" not in containerClass:
print ("structure of the metadata in snippet is wrong")
return
else:
print ("Error: structure of metadata is wrong, \neach field should devided with \",\" and each object is devided with \":\"", "\nFor example: Revision: P.00.00, Approved: True")
# Check if item has not been approved before transitioning between states
if "False" in Approved and NextState != CurrectState:
warning = "With warning: the information container had not been approved before transitioning!"
print ("Warning: the information container has not been approved!")
else:warning = None
# updating metadata with required data accordingly
revision = updateRevision(CurrectState, NextState,revision, categories)
lastUpdate = lastUpdate.split(":")[0] + ": "+ userName
Approved = Approved.split(":")[0] + ": " + "False"
# composing metadat of the updated parameters
if parameters == 4: returnedMetadata = revision + "," + Approved + "," + lastUpdate + "," + containerClass
else:returnedMetadata = revision + "," + Approved + "," + lastUpdate
# update item with updated metadata
update_Snippet_Or_Description_SRC(AuthenticationToken, itemid, userName, tags=tagsL, SRC=returnedMetadata, SnippetOrDescription=snippetOrDisc, portal_URL= portal_URL)
# update the item category in the group
updateItemsCategoriesOfGroup(AuthenticationToken, groupid, itemid, state = NextState, status =statusPush, portal_URL = portal_URL, isoStateStatus = categories)
# ask the user for adding comment to register the transionning action of the container
commentUsser = input("Add a comment...")
if commentUsser == "": commentUsser = "No comment"
commentUsser = f"{CurrectState} to {NextState}: {commentUsser}"
if warning: commentUsser = commentUsser + f"\n{warning}"
addComment(AuthenticationToken, itemid=itemid, Comment=commentUsser , portal_URL=portal_URL)
else:
print ("Error: Invalid state or incompatible state and status provided\nWarning: push function works only between WIP, shared, and published states")
# to be continueed
# This function makes the item reference data for the project (existing project related data)
def makeReferenceData(AuthenticationToken, itemID, GroupID, userName, ContainerClassification = None, categories = IsoCategories, portal_URL = r"https://www.arcgis.com"):
if ContainerClassification:update_Snippet_Or_Description_SRC(AuthenticationToken, itemID, userName, tags=[categories[0]['categories'][4]['title']],
SRC=f"{categories[0]['categories'][4]['title']}, Last updated by: {userName}, Container classification: {ContainerClassification}", portal_URL=portal_URL)
else:update_Snippet_Or_Description_SRC(AuthenticationToken, itemID, userName, tags=[categories[0]['categories'][4]['title']],
SRC=f"{categories[0]['categories'][4]['title']}, Last updated by: {userName}", portal_URL=portal_URL)
return updateItemsCategoriesOfGroup(AuthenticationToken, GroupID, itemID, categories[0]['categories'][4]['title'], portal_URL = portal_URL, isoStateStatus= categories )
# This function intialize the required metadata for an item
def initilizemetadataOfitem(AuthenticationToken, itemID, GroupID, userName, ContainerClassification = None, categories = IsoCategories, portal_URL = r"https://www.arcgis.com"):
tags = getItemMetadataAndTags(AuthenticationToken, itemID, portal_URL=portal_URL)[1]
tags = updateTags(categories[0]['categories'][0]['title'], categories[0]['categories'][0]['title'],tags )
if ContainerClassification: update_Snippet_Or_Description_SRC(AuthenticationToken, itemID, userName, tags=tags,
SRC=f"Revision: P.00.00, Approved: False, Last updated by: {userName}, Container classification: {ContainerClassification}", portal_URL=portal_URL)
else:update_Snippet_Or_Description_SRC(AuthenticationToken, itemID, userName, tags=tags,
SRC=f"Revision: P.00.00, Approved: False, Last updated by: {userName}", portal_URL=portal_URL)
return updateItemsCategoriesOfGroup(AuthenticationToken, GroupID, itemID, categories[0]['categories'][0]['title'], portal_URL = portal_URL, isoStateStatus= categories )
if __name__ == '__main__':
pass