-
Notifications
You must be signed in to change notification settings - Fork 1
/
pgdl-conv.py
276 lines (243 loc) · 10.2 KB
/
pgdl-conv.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
#!/usr/bin/python3
import argparse
import json
import cbor
from xml.dom.minidom import parseString
import qtoml
import dicttoxml
import yaml
from rdflib import Graph, Literal, BNode, Namespace, RDF, URIRef
parser = argparse.ArgumentParser(description='Process PGDL documents.')
parser.add_argument('file', type=str,
help='a PGDL file')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("-m", "--metadata", help="display PGDL metadata",
action="store_true")
group.add_argument("-j", "--json", help="display PGDL in JSON",
action="store_true")
group.add_argument("-pj", "--prettyjson", help="display PGDL in pretty JSON",
action="store_true")
group.add_argument("-c", "--cbor", help="display PGDL in CBOR (binary JSON)",
action="store_true")
group.add_argument("-x", "--xml", help="display PDGL in XML",
action="store_true")
group.add_argument("-px", "--prettyxml", help="display PDGL in pretty XML",
action="store_true")
group.add_argument("-t", "--toml", help="display TOML",
action="store_true")
group.add_argument("-y", "--yaml", help="display PDGL in compact YAML",
action="store_true")
# parser.add_argument("-py", "--prettyyaml", help="display PDGL in compact YAML",
# action="store_true")
group.add_argument("-p", "--pgdl", help="display PDGL (in YAML)",
action="store_true")
group.add_argument("-g", "--graphql", help="display GraphQL",
action="store_true")
group.add_argument("-s", "--shacl", help="display (PG)SHACL (in RDF)",
action="store_true")
args = parser.parse_args()
if args.file:
with open(args.file, 'r') as stream:
try:
data = yaml.load(stream, Loader=yaml.SafeLoader)
with open(args.file, 'r') as s:
raw = s.read()
except yaml.YAMLError as exc:
print(exc)
exit()
if args.metadata:
try:
print('PGDL domument data creation: ' + data['metadata']['created'])
except:
print('There are not any information about PGDL data creation')
try:
print('Document is created by ' + data['metadata']['creator'])
except:
print('There are not any information about PGDL creator')
exit()
print(data['shapes'][0]['targetClass'])
if args.json:
json = json.dumps(data)
print(json)
if args.cbor:
cbor = cbor.dumps(data)
print(cbor)
if args.prettyjson:
json = json.dumps(data, indent=2, sort_keys=True)
print(json)
if args.xml:
xml = dicttoxml.dicttoxml(data, attr_type=False, custom_root='pgdl')
print(xml.decode("utf-8"))
if args.prettyxml:
xml = dicttoxml.dicttoxml(data, attr_type=False, custom_root='pgdl')
x = xml.decode("utf-8")
dom = parseString(x)
print(dom.toprettyxml())
if args.toml:
toml = qtoml.dumps(data)
print(toml)
if args.yaml:
print(yaml.dump(data))
if args.pgdl:
print(raw)
if args.graphql:
indentation = ' '
def set_datatype(f):
if f == 'string':
return 'String'
elif f == 'int':
return 'Int'
elif f == 'integer':
return 'Int'
elif f == 'boolean':
return 'Boolean'
elif f == 'decimal':
return 'Float'
elif f == 'float':
return 'Float'
elif f == 'double':
return 'Float'
elif f == 'dateTime':
return 'String'
elif f == 'time':
return 'String'
elif f == 'date':
return 'String'
def print_edge_details(pnd, direction):
if edge_directed:
print(indentation + pnd.lower() + 's: [' + pnd + '] @relation(name:\"' +
pp1 + '\",direction:' + direction + ')')
else:
print(indentation + pnd.lower() + 's: [' + pnd + '] @relation(name:\"' + pp1 + ')')
def print_relation_details():
print(indentation + '@property(name:' + '\"' + nky1 + '\",datatype:\"' + rdt1 + '\")')
for shape in data.get('shapes', []):
try:
tn1 = shape['targetClass']
print('type ' + tn1 + ' {')
except:
print('# There is no information about target node')
for property in shape.get('properties', []):
try:
pn1 = property['name']
pdt1 = property['datatype']
pdt1 = set_datatype(pdt1)
print(indentation + pn1 + ': ' + pdt1 + '!')
except:
print(indentation + '# There is no information about property name or data type')
try:
for edge in shape['edges']:
try:
edge_directed = edge['directed']
except:
edge_directed = None
print(indentation + '# There is no information about edge direction')
try:
pp1 = edge['name']
except:
print(indentation + '# There is no information about edge name')
try:
pnd1 = edge['node']
except:
print(indentation + '# There is no information about edge node')
try:
print_edge_details(pnd1, 'OUT')
except:
print(indentation + '# Error while printing edge details')
for relation in edge.get('relations', []):
try:
nky1 = relation['name']
except:
print(indentation + '# There is no information about relation name')
try:
rdt1 = relation['datatype']
rdt1 = set_datatype(rdt1)
print_relation_details()
except:
print(indentation + '# There is no information about relation datatype')
except:
# print(indentation + '# There is no information about edge.')
try:
for sh in data.get('shapes', []):
if sh['targetClass'] == pnd1:
# TODO
print_edge_details('Person', 'IN')
print_relation_details()
except:
print(indentation + '# Failed to add edge & relationship information')
print('}\n')
if args.shacl:
g = Graph()
doc = BNode()
dct = Namespace("http://purl.org/dc/terms/")
sh = Namespace("http://www.w3.org/ns/shacl#")
pg = Namespace("urn:pg:1.0:")
xsd = Namespace("http://www.w3.org/2001/XMLSchema#")
pgsh = Namespace("http://ii.uwb.edu.pl/shpg#")
g.bind("shpg", pgsh)
def set_datatype(f):
return {
'string': xsd.string,
'int': xsd.int,
'integer': xsd.integer,
'boolean': xsd.boolean,
'decimal': xsd.decimal,
'float': xsd.float,
'double': xsd.double,
'dateTime': xsd.dateTime,
'time': xsd.time,
'date': xsd.date,
}.get(f)
try:
created = data['metadata']['created']
g.add((doc, dct.created, Literal(created, datatype=xsd.date)))
except KeyError:
print('# There is no information about date of creation')
try:
creator = data['metadata']['creator']
g.add((doc, dct.creator, Literal(creator)))
except KeyError:
print('# There is no information about creator')
shape_counter = 1
for shape in data.get('shapes', []):
shape_id = f"Shape{shape_counter}"
shape_counter += 1
try:
tn1 = shape['targetClass']
shape_ref = URIRef(f"urn:pg:1.0:{shape_id}")
g.add((shape_ref, RDF.type, sh.NodeShape))
g.add((shape_ref, sh.targetClass, URIRef("urn:pg:1.0:" + tn1)))
except KeyError:
print('# There is no information about target node')
for property in shape.get('properties', []):
prop = BNode()
try:
pn1 = property['name']
g.add((shape_ref, sh.property, prop))
g.add((prop, sh.path, URIRef("urn:pg:1.0:" + pn1)))
pdt1 = set_datatype(property.get('datatype'))
if pdt1:
g.add((prop, sh.datatype, pdt1))
except KeyError as e:
print(f'# There is no information about property: {e}')
for edge in shape.get('edges', []):
prop2 = BNode()
try:
pp1 = edge['name']
g.add((shape_ref, sh.property, prop2))
g.add((prop2, sh.path, URIRef("urn:pg:1.0:" + pp1)))
pnd1 = edge['node']
g.add((prop2, sh.node, URIRef("urn:pg:1.0:" + pnd1)))
rel = BNode()
g.add((prop2, pgsh.relation, rel))
for relation in edge.get('relations', []):
nky1 = relation['name']
g.add((rel, pgsh.key, URIRef("urn:pg:1.0:" + nky1)))
rdt1 = set_datatype(relation.get('datatype'))
if rdt1:
g.add((rel, sh.datatype, rdt1))
except KeyError as e:
print(f'# There is no information about edge or relation: {e}')
print(g.serialize(format='turtle'))
else:
parser.print_help()