json-duplicate-keys 2024.7.17__py2-none-any.whl → 2024.11.19__py2-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,8 @@
1
+ try:
2
+ unicode # Python 2
3
+ except NameError:
4
+ unicode = str # Python 3
5
+
1
6
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
2
7
  # # # # # # # # # # # Normalize Key name # # # # # # # # # # #
3
8
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -7,18 +12,13 @@ def normalize_key(name, dupSign_start="{{{", dupSign_end="}}}", _isDebug_=False)
7
12
  # User input data type validation
8
13
  if type(_isDebug_) != bool: _isDebug_ = False
9
14
 
10
- try:
11
- if type(name) not in [str, unicode]: exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
12
-
13
- if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
14
-
15
- if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
16
- except Exception as e:
17
- if type(name) not in [str]: exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
15
+ if type(name) not in [str, unicode]:
16
+ if _isDebug_: print("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
17
+ return False
18
18
 
19
- if type(dupSign_start) not in [str]: dupSign_start = "{{{"
19
+ if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
20
20
 
21
- if type(dupSign_end) not in [str]: dupSign_end = "}}}"
21
+ if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
22
22
 
23
23
  return re.sub('{dupSign_start}_\\d+_{dupSign_end}$'.format(dupSign_start=re.escape(dupSign_start), dupSign_end=re.escape(dupSign_end)), "", name)
24
24
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -38,18 +38,13 @@ def loads(Jstr, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isD
38
38
 
39
39
  if type(ordered_dict) != bool: ordered_dict = False
40
40
 
41
- try:
42
- if type(Jstr) not in [str, unicode]: exit("\x1b[31m[-] DataTypeError: the JSON object must be str or unicode, not {}\x1b[0m".format(type(Jstr)))
43
-
44
- if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
45
-
46
- if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
47
- except Exception as e:
48
- if type(Jstr) not in [str]: exit("\x1b[31m[-] DataTypeError: the JSON object must be str or unicode, not {}\x1b[0m".format(type(Jstr)))
41
+ if type(Jstr) not in [str, unicode]:
42
+ if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be str or unicode, not {}\x1b[0m".format(type(Jstr)))
43
+ return False
49
44
 
50
- if type(dupSign_start) not in [str]: dupSign_start = "{{{"
45
+ if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
51
46
 
52
- if type(dupSign_end) not in [str]: dupSign_end = "}}}"
47
+ if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
53
48
 
54
49
  def __convert_Jloads_to_Jobj(Jloads, Jobj):
55
50
  if type(Jloads) in [dict, OrderedDict]:
@@ -141,8 +136,10 @@ def loads(Jstr, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isD
141
136
  return JSON_DUPLICATE_KEYS(Jobj)
142
137
  else:
143
138
  if _isDebug_: print("\x1b[31m[-] DataError: Invalid JSON format\x1b[0m")
139
+ return False
144
140
  except Exception as e:
145
141
  if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
142
+ return False
146
143
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
147
144
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
148
145
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -160,6 +157,7 @@ def load(Jfilepath, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False,
160
157
  return loads(Jstr, dupSign_start=dupSign_start, dupSign_end=dupSign_end, ordered_dict=ordered_dict, _isDebug_=_isDebug_)
161
158
  except Exception as e:
162
159
  if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
160
+ return False
163
161
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
164
162
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
165
163
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -189,49 +187,57 @@ class JSON_DUPLICATE_KEYS:
189
187
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
190
188
  # # # # # # # # # # # # # # # get # # # # # # # # # # # # # # #
191
189
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
192
- def get(self, name, separator="||", parse_index="$", _isDebug_=False):
190
+ def get(self, name, case_insensitive=False, separator="||", parse_index="$", _isDebug_=False):
193
191
  import re
194
192
  from collections import OrderedDict
195
193
 
196
194
  # User input data type validation
197
195
  if type(_isDebug_) != bool: _isDebug_ = False
198
196
 
199
- try:
200
- if type(name) not in [str, unicode]: exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
201
-
202
- if type(separator) not in [str, unicode]: separator = "||"
197
+ if type(name) not in [str, unicode]:
198
+ if _isDebug_: print("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
199
+ return {"name":name, "value":"JSON_DUPLICATE_KEYS_ERROR"}
203
200
 
204
- if type(parse_index) not in [str, unicode]: parse_index = "$"
205
- except Exception as e:
206
- if type(name) not in [str]: exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
201
+ if type(case_insensitive) != bool: case_insensitive = False
207
202
 
208
- if type(separator) not in [str]: separator = "||"
203
+ if type(separator) not in [str, unicode]: separator = "||"
209
204
 
210
- if type(parse_index) not in [str]: parse_index = "$"
205
+ if type(parse_index) not in [str, unicode]: parse_index = "$"
211
206
 
212
207
  if type(self.getObject()) not in [list, dict, OrderedDict]:
213
208
  if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be list, dict or OrderedDict, not {}\x1b[0m".format(type(self.getObject())))
214
- return "JSON_DUPLICATE_KEYS_ERROR"
209
+ return {"name":name, "value":"JSON_DUPLICATE_KEYS_ERROR"}
210
+
211
+ if re.search(re.escape(separator)+"$", name):
212
+ if _isDebug_: print("\x1b[31m[-] KeyNameInvalidError: \x1b[0m"+name)
213
+ return {"name":name, "value":"JSON_DUPLICATE_KEYS_ERROR"}
214
+
215
+ Jobj = JSON_DUPLICATE_KEYS(self.__Jobj)
216
+ Jobj.flatten()
217
+ Jname = []
218
+ Jval = self.__Jobj
219
+ name_split = name.split(separator)
220
+ for k in Jobj.getObject().keys():
221
+ if len(k.split(separator)) >= len(name_split):
222
+ if case_insensitive:
223
+ if separator.join(k.split(separator)[:len(name_split)]).lower() == name.lower():
224
+ Jname = k.split(separator)[:len(name_split)]
225
+ break
226
+ else:
227
+ if separator.join(k.split(separator)[:len(name_split)]) == name:
228
+ Jname = name_split
229
+ break
215
230
 
216
- try:
217
- Jobj = self.__Jobj
218
- Jval = "JSON_DUPLICATE_KEYS_ERROR"
219
- name_split = name.split(separator)
220
-
221
- for i in range(len(name_split)):
222
- if type(Jobj) in [dict, OrderedDict] and name_split[i] in Jobj.keys():
223
- Jval = Jobj[name_split[i]]
224
- Jobj = Jobj[name_split[i]]
225
- elif type(Jobj) in [list] and re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", name_split[i]):
226
- Jval = Jobj[int(name_split[i].split(parse_index)[1])]
227
- Jobj = Jobj[int(name_split[i].split(parse_index)[1])]
231
+ if len(Jname) > 0:
232
+ for k in Jname:
233
+ if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
234
+ Jval = Jval[int(k.split(parse_index)[1])]
228
235
  else:
229
- if _isDebug_: print("\x1b[31m[-] KeyNotFoundError: \x1b[0m"+separator.join(name_split[:i+1]))
230
- return "JSON_DUPLICATE_KEYS_ERROR"
231
- return Jval
232
- except Exception as e:
233
- if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
234
- return "JSON_DUPLICATE_KEYS_ERROR"
236
+ Jval = Jval[k]
237
+ return {"name":separator.join(Jname), "value":Jval}
238
+ else:
239
+ if _isDebug_: print("\x1b[31m[-] KeyNotFoundError: \x1b[0m"+name)
240
+ return {"name":name, "value":"JSON_DUPLICATE_KEYS_ERROR"}
235
241
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
236
242
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
237
243
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -240,7 +246,7 @@ class JSON_DUPLICATE_KEYS:
240
246
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
241
247
  # # # # # # # # # # # # # # # set # # # # # # # # # # # # # # #
242
248
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
243
- def set(self, name, value, separator="||", parse_index="$", dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isDebug_=False):
249
+ def set(self, name, value, case_insensitive=False, separator="||", parse_index="$", dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isDebug_=False):
244
250
  import re
245
251
  from collections import OrderedDict
246
252
 
@@ -249,144 +255,71 @@ class JSON_DUPLICATE_KEYS:
249
255
 
250
256
  if type(ordered_dict) != bool: ordered_dict = False
251
257
 
252
- try:
253
- if type(name) not in [str, unicode]: exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
254
-
255
- if type(separator) not in [str, unicode]: separator = "||"
256
-
257
- if type(parse_index) not in [str, unicode]: parse_index = "$"
258
+ if type(name) not in [str, unicode]:
259
+ if _isDebug_: print("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
260
+ return False
258
261
 
259
- if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
262
+ if type(case_insensitive) != bool: case_insensitive = False
260
263
 
261
- if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
262
- except Exception as e:
263
- if type(name) not in [str]: exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
264
+ if type(separator) not in [str, unicode]: separator = "||"
264
265
 
265
- if type(separator) not in [str]: separator = "||"
266
+ if type(parse_index) not in [str, unicode]: parse_index = "$"
266
267
 
267
- if type(parse_index) not in [str]: parse_index = "$"
268
-
269
- if type(dupSign_start) not in [str]: dupSign_start = "{{{"
268
+ if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
270
269
 
271
- if type(dupSign_end) not in [str]: dupSign_end = "}}}"
270
+ if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
272
271
 
273
272
  if type(self.getObject()) not in [list, dict, OrderedDict]:
274
273
  if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be list, dict or OrderedDict, not {}\x1b[0m".format(type(self.getObject())))
275
274
  return False
276
275
 
277
- try:
278
- name_split = name.split(separator)
279
- name_split_first = name_split[:-1]
280
- name_split_lastKey = name_split[-1]
276
+ if re.search(re.escape(separator)+"$", name):
277
+ if _isDebug_: print("\x1b[31m[-] KeyNameInvalidError: \x1b[0m"+name)
278
+ return False
281
279
 
282
- if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", name_split_lastKey):
283
- if _isDebug_: print("\x1b[31m[-] KeyNameInvalidError: The key name does not end with the list index\x1b[0m")
284
- return False
280
+ if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", name.split(separator)[-1]):
281
+ if _isDebug_: print("\x1b[31m[-] KeyNameInvalidError: The key name does not end with the list index\x1b[0m")
282
+ return False
285
283
 
286
- """
287
- name = name_split_first||name_split_lastKey
288
-
289
- if "name" exist in "self.getObject()"
290
- => Add duplicate key
291
- else if "name_split_first" exist in "self.getObject()"
292
- if typeof "name_split_first" is list
293
- if length of "name_split_lastKey" is 0
294
- => Add new key (append "value" to "name_split_first")
295
- else
296
- => Add new key (append dict "name_split_lastKey"/"value" to "name_split_first")
297
- else if typeof "name_split_first" is dict
298
- => Add new key ( name_split_first[name_split_lastKey] = value )
299
- else if length of "name_split_first" is 0 => Add new key
300
- if typeof self.getObject() is list
301
- if length of "name_split_lastKey" is 0
302
- => Add new key (append "value" to self.__Jobj)
303
- else
304
- => Add new key (append dict "name_split_lastKey"/"value" to self.__Jobj)
305
- else if typeof self.getObject() is dict
306
- => Add new key ( self.__Jobj[name_split_lastKey] = value )
307
- """
308
- # Add duplicate key
309
- if self.get(separator.join(name_split), separator=separator, parse_index=parse_index) != "JSON_DUPLICATE_KEYS_ERROR":
310
- index = 2
311
- while True:
312
- if self.get(separator.join(name_split)+dupSign_start+"_"+str(index)+"_"+dupSign_end, separator=separator, parse_index=parse_index) == "JSON_DUPLICATE_KEYS_ERROR":
313
- break
314
- index += 1
284
+ Jget = self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)
315
285
 
316
- exec_expression = "self.getObject()"
286
+ if Jget["value"] != "JSON_DUPLICATE_KEYS_ERROR":
287
+ index = 2
288
+ while True:
289
+ if self.get(Jget["name"]+dupSign_start+"_"+str(index)+"_"+dupSign_end, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)["value"] == "JSON_DUPLICATE_KEYS_ERROR":
290
+ break
291
+ index += 1
317
292
 
318
- name_split[-1] = name_split[-1]+dupSign_start+"_"+str(index)+"_"+dupSign_end
319
- for k in name_split:
320
- if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
321
- exec_expression += "["+k.split(parse_index)[1]+"]"
322
- else:
323
- exec_expression += "["+repr(k)+"]"
293
+ exec_expression = "self.getObject()"
324
294
 
325
- exec(exec_expression+"="+repr(value))
326
- return True
327
- # Add new key
328
- elif self.get(separator.join(name_split_first), separator=separator, parse_index=parse_index) != "JSON_DUPLICATE_KEYS_ERROR":
329
- if len(name_split_first) > 0:
330
- if type(self.get(separator.join(name_split_first), separator=separator, parse_index=parse_index)) == list:
331
- if name_split_lastKey == "":
332
- exec_expression = "self.getObject()"
333
-
334
- for k in name_split_first:
335
- if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
336
- exec_expression += "["+k.split(parse_index)[1]+"]"
337
- else:
338
- exec_expression += "["+repr(k)+"]"
339
-
340
- exec(exec_expression+".append("+repr(value)+")")
341
- else:
342
- exec_expression = "self.getObject()"
343
-
344
- for k in name_split_first:
345
- if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
346
- exec_expression += "["+k.split(parse_index)[1]+"]"
347
- else:
348
- exec_expression += "["+repr(k)+"]"
349
-
350
- exec(exec_expression+".append({"+repr(name_split_lastKey)+":"+repr(value)+"})")
351
- return True
352
- elif type(self.get(separator.join(name_split_first), separator=separator, parse_index=parse_index)) == dict:
353
- exec_expression = "self.getObject()"
354
-
355
- for k in name_split_first:
356
- if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
357
- exec_expression += "["+k.split(parse_index)[1]+"]"
358
- else:
359
- exec_expression += "["+repr(k)+"]"
360
-
361
- exec(exec_expression+"["+repr(name_split_lastKey)+"]="+repr(value))
362
- return True
363
- else:
364
- if _isDebug_: print("\x1b[31m[-] KeyNameNotExistError: {}\x1b[0m".format(separator.join(name_split_first)))
295
+ for k in (Jget["name"]+dupSign_start+"_"+str(index)+"_"+dupSign_end).split(separator):
296
+ if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
297
+ exec_expression += "["+k.split(parse_index)[1]+"]"
365
298
  else:
366
- if type(self.getObject()) == list:
367
- if name_split_lastKey == "":
368
- self.__Jobj.append(value)
369
- else:
370
- self.__Jobj.append({name_split_lastKey: value})
371
- else:
372
- self.__Jobj[name_split_lastKey] = value
373
- return True
374
- # Add new key
375
- elif len(name_split_first) == 0:
376
- if type(self.getObject()) == list:
377
- if name_split_lastKey == "":
378
- self.__Jobj.append(value)
379
- else:
380
- self.__Jobj.append({name_split_lastKey: value})
381
- else:
382
- self.__Jobj[name_split_lastKey] = value
299
+ exec_expression += "["+repr(k)+"]"
300
+
301
+ exec(exec_expression+"="+repr(value))
302
+ return True
303
+ else:
304
+ if len(name.split(separator)) == 1:
305
+ self.getObject()[name] = value
383
306
  return True
384
307
  else:
385
- if _isDebug_: print("\x1b[31m[-] KeyNameInvalidError: {}\x1b[0m".format(separator.join(name_split_first)))
386
- except Exception as e:
387
- if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
308
+ if self.get(separator.join(name.split(separator)[:-1]), case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)["value"] != "JSON_DUPLICATE_KEYS_ERROR":
309
+ Jget = self.get(separator.join(name.split(separator)[:-1]), case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)
310
+ exec_expression = "self.getObject()"
388
311
 
389
- return False
312
+ for k in Jget["name"].split(separator):
313
+ if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
314
+ exec_expression += "["+k.split(parse_index)[1]+"]"
315
+ else:
316
+ exec_expression += "["+repr(k)+"]"
317
+
318
+ exec(exec_expression+"="+repr(value))
319
+ return True
320
+ else:
321
+ if _isDebug_: print("\x1b[31m[-] KeyNameNotExistError: {}\x1b[0m".format(separator.join(Jget["name"].split(separator)[:-1])))
322
+ return False
390
323
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
391
324
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
392
325
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -395,30 +328,28 @@ class JSON_DUPLICATE_KEYS:
395
328
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
396
329
  # # # # # # # # # # # # # # update # # # # # # # # # # # # # #
397
330
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
398
- def update(self, name, value, separator="||", parse_index="$", _isDebug_=False):
331
+ def update(self, name, value, case_insensitive=False, separator="||", parse_index="$", _isDebug_=False):
399
332
  import re
400
333
 
401
334
  # User input data type validation
402
335
  if type(_isDebug_) != bool: _isDebug_ = False
403
336
 
404
- try:
405
- if type(name) not in [str, unicode]: exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
406
-
407
- if type(separator) not in [str, unicode]: separator = "||"
337
+ if type(name) not in [str, unicode]:
338
+ if _isDebug_: print("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
339
+ return False
408
340
 
409
- if type(parse_index) not in [str, unicode]: parse_index = "$"
410
- except Exception as e:
411
- if type(name) not in [str]: exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
341
+ if type(case_insensitive) != bool: case_insensitive = False
412
342
 
413
- if type(separator) not in [str]: separator = "||"
343
+ if type(separator) not in [str, unicode]: separator = "||"
414
344
 
415
- if type(parse_index) not in [str]: parse_index = "$"
345
+ if type(parse_index) not in [str, unicode]: parse_index = "$"
416
346
 
417
- if self.get(name, separator=separator, parse_index=parse_index, _isDebug_=_isDebug_) != "JSON_DUPLICATE_KEYS_ERROR":
347
+ if self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index, _isDebug_=_isDebug_)["value"] != "JSON_DUPLICATE_KEYS_ERROR":
348
+ Jname = self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)["name"]
418
349
  try:
419
350
  exec_expression = "self.getObject()"
420
351
 
421
- for k in name.split(separator):
352
+ for k in Jname.split(separator):
422
353
  if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
423
354
  exec_expression += "["+k.split(parse_index)[1]+"]"
424
355
  else:
@@ -438,30 +369,28 @@ class JSON_DUPLICATE_KEYS:
438
369
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
439
370
  # # # # # # # # # # # # # # delete # # # # # # # # # # # # #
440
371
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
441
- def delete(self, name, separator="||", parse_index="$", _isDebug_=False):
372
+ def delete(self, name, case_insensitive=False, separator="||", parse_index="$", _isDebug_=False):
442
373
  import re
443
374
 
444
375
  # User input data type validation
445
376
  if type(_isDebug_) != bool: _isDebug_ = False
446
377
 
447
- try:
448
- if type(name) not in [str, unicode]: exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
449
-
450
- if type(separator) not in [str, unicode]: separator = "||"
378
+ if type(name) not in [str, unicode]:
379
+ if _isDebug_: print("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
380
+ return False
451
381
 
452
- if type(parse_index) not in [str, unicode]: parse_index = "$"
453
- except Exception as e:
454
- if type(name) not in [str]: exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
382
+ if type(case_insensitive) != bool: case_insensitive = False
455
383
 
456
- if type(separator) not in [str]: separator = "||"
384
+ if type(separator) not in [str, unicode]: separator = "||"
457
385
 
458
- if type(parse_index) not in [str]: parse_index = "$"
386
+ if type(parse_index) not in [str, unicode]: parse_index = "$"
459
387
 
460
- if self.get(name, separator=separator, parse_index=parse_index, _isDebug_=_isDebug_) != "JSON_DUPLICATE_KEYS_ERROR":
388
+ if self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index, _isDebug_=_isDebug_)["value"] != "JSON_DUPLICATE_KEYS_ERROR":
389
+ Jname = self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)["name"]
461
390
  try:
462
391
  exec_expression = "del self.getObject()"
463
392
 
464
- for k in name.split(separator):
393
+ for k in Jname.split(separator):
465
394
  if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
466
395
  exec_expression += "["+k.split(parse_index)[1]+"]"
467
396
  else:
@@ -491,10 +420,10 @@ class JSON_DUPLICATE_KEYS:
491
420
  for k, v in JDKSObject.getObject().items():
492
421
  if type(k) == str and type(name) == str:
493
422
  if re.search(name, k):
494
- newJDKSObject.set(k, v, separator="§§"+separator+"§§", parse_index="§§"+parse_index+"§§", ordered_dict=ordered_dict)
423
+ newJDKSObject.set(k, v, separator="!!"+separator+"!!", parse_index="!!"+parse_index+"!!", ordered_dict=ordered_dict)
495
424
  else:
496
425
  if name == k:
497
- newJDKSObject.set(k, v, separator="§§"+separator+"§§", parse_index="§§"+parse_index+"§§", ordered_dict=ordered_dict)
426
+ newJDKSObject.set(k, v, separator="!!"+separator+"!!", parse_index="!!"+parse_index+"!!", ordered_dict=ordered_dict)
498
427
 
499
428
  return newJDKSObject
500
429
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -515,10 +444,10 @@ class JSON_DUPLICATE_KEYS:
515
444
  for k, v in JDKSObject.getObject().items():
516
445
  if type(v) == str and type(value) == str:
517
446
  if re.search(value, v):
518
- newJDKSObject.set(k, v, separator="§§"+separator+"§§", parse_index="§§"+parse_index+"§§", ordered_dict=ordered_dict)
447
+ newJDKSObject.set(k, v, separator="!!"+separator+"!!", parse_index="!!"+parse_index+"!!", ordered_dict=ordered_dict)
519
448
  else:
520
449
  if value == v:
521
- newJDKSObject.set(k, v, separator="§§"+separator+"§§", parse_index="§§"+parse_index+"§§", ordered_dict=ordered_dict)
450
+ newJDKSObject.set(k, v, separator="!!"+separator+"!!", parse_index="!!"+parse_index+"!!", ordered_dict=ordered_dict)
522
451
 
523
452
  return newJDKSObject
524
453
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -536,14 +465,9 @@ class JSON_DUPLICATE_KEYS:
536
465
  # User input data type validation
537
466
  if type(_isDebug_) != bool: _isDebug_ = False
538
467
 
539
- try:
540
- if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
541
-
542
- if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
543
- except Exception as e:
544
- if type(dupSign_start) not in [str]: dupSign_start = "{{{"
468
+ if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
545
469
 
546
- if type(dupSign_end) not in [str]: dupSign_end = "}}}"
470
+ if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
547
471
 
548
472
  if type(self.getObject()) not in [list, dict, OrderedDict]:
549
473
  if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be list, dict or OrderedDict, not {}\x1b[0m".format(type(self.getObject())))
@@ -553,7 +477,7 @@ class JSON_DUPLICATE_KEYS:
553
477
 
554
478
  dupSign_end_escape_regex = re.escape(json.dumps({dupSign_end:""})[2:-6])
555
479
 
556
- return re.sub(r'{dupSign_start}_\\d+_{dupSign_end}":'.format(dupSign_start=dupSign_start_escape_regex, dupSign_end=dupSign_end_escape_regex), '":', json.dumps(self.getObject(), skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, cls=cls, indent=indent, separators=separators, default=default, sort_keys=sort_keys))
480
+ return re.sub('{dupSign_start}_\\d+_{dupSign_end}":'.format(dupSign_start=dupSign_start_escape_regex, dupSign_end=dupSign_end_escape_regex), '":', json.dumps(self.getObject(), skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, cls=cls, indent=indent, separators=separators, default=default, sort_keys=sort_keys))
557
481
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
558
482
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
559
483
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -571,6 +495,7 @@ class JSON_DUPLICATE_KEYS:
571
495
  Jfile.close()
572
496
  except Exception as e:
573
497
  if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
498
+ return False
574
499
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
575
500
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
576
501
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -587,18 +512,13 @@ class JSON_DUPLICATE_KEYS:
587
512
 
588
513
  if type(ordered_dict) != bool: ordered_dict = False
589
514
 
590
- try:
591
- if type(separator) not in [str, unicode]: separator = "||"
515
+ if type(separator) not in [str, unicode]: separator = "||"
592
516
 
593
- if type(parse_index) not in [str, unicode]: parse_index = "$"
594
- except Exception as e:
595
- if type(separator) not in [str]: separator = "||"
596
-
597
- if type(parse_index) not in [str]: parse_index = "$"
517
+ if type(parse_index) not in [str, unicode]: parse_index = "$"
598
518
 
599
519
  if type(self.getObject()) not in [list, dict, OrderedDict]:
600
520
  if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be list, dict or OrderedDict, not {}\x1b[0m".format(type(self.getObject())))
601
- exit()
521
+ return False
602
522
 
603
523
  if len(self.getObject()) > 0:
604
524
  try:
@@ -633,8 +553,10 @@ class JSON_DUPLICATE_KEYS:
633
553
  __convert_Jobj_to_Jflat(self.getObject())
634
554
 
635
555
  self.__Jobj = Jflat
556
+ return True
636
557
  except Exception as e:
637
558
  if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
559
+ return False
638
560
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
639
561
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
640
562
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -652,18 +574,13 @@ class JSON_DUPLICATE_KEYS:
652
574
 
653
575
  if type(ordered_dict) != bool: ordered_dict = False
654
576
 
655
- try:
656
- if type(separator) not in [str, unicode]: separator = "||"
577
+ if type(separator) not in [str, unicode]: separator = "||"
657
578
 
658
- if type(parse_index) not in [str, unicode]: parse_index = "$"
659
- except Exception as e:
660
- if type(separator) not in [str]: separator = "||"
661
-
662
- if type(parse_index) not in [str]: parse_index = "$"
579
+ if type(parse_index) not in [str, unicode]: parse_index = "$"
663
580
 
664
581
  if type(self.getObject()) not in [dict, OrderedDict]:
665
582
  if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be dict or OrderedDict, not {}\x1b[0m".format(type(self.getObject())))
666
- exit()
583
+ return False
667
584
 
668
585
  if len(self.getObject()) > 0:
669
586
  try:
@@ -688,8 +605,10 @@ class JSON_DUPLICATE_KEYS:
688
605
  Jtmp = Jtmp[Jkey]
689
606
 
690
607
  self.__Jobj = Jobj
608
+ return True
691
609
  except Exception as e:
692
610
  if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
611
+ return False
693
612
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
694
613
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
695
614
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: json-duplicate-keys
3
- Version: 2024.7.17
3
+ Version: 2024.11.19
4
4
  Summary: Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys
5
5
  Home-page: https://github.com/truocphan/json-duplicate-keys
6
6
  Author: TP Cyber Security
@@ -23,12 +23,6 @@ Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys
23
23
  <a href="#"><img src="https://img.shields.io/github/forks/truocphan/json-duplicate-keys" height=30></a>
24
24
  <a href="https://github.com/truocphan/json-duplicate-keys/issues?q=is%3Aopen+is%3Aissue"><img src="https://img.shields.io/github/issues/truocphan/json-duplicate-keys" height=30></a>
25
25
  <a href="https://github.com/truocphan/json-duplicate-keys/issues?q=is%3Aissue+is%3Aclosed"><img src="https://img.shields.io/github/issues-closed/truocphan/json-duplicate-keys" height=30></a>
26
- <a href="https://pypi.org/project/json-duplicate-keys/" target="_blank"><img src="https://img.shields.io/badge/pypi-3775A9?style=for-the-badge&logo=pypi&logoColor=white" height=30></a>
27
- <a href="https://www.facebook.com/61550595106970" target="_blank"><img src="https://img.shields.io/badge/Facebook-1877F2?style=for-the-badge&logo=facebook&logoColor=white" height=30></a>
28
- <a href="https://twitter.com/TPCyberSec" target="_blank"><img src="https://img.shields.io/badge/Twitter-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white" height=30></a>
29
- <a href="https://github.com/truocphan" target="_blank"><img src="https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white" height=30></a>
30
- <a href="mailto:tpcybersec2023@gmail.com" target="_blank"><img src="https://img.shields.io/badge/Gmail-D14836?style=for-the-badge&logo=gmail&logoColor=white" height=30></a>
31
- <a href="https://www.buymeacoffee.com/truocphan" target="_blank"><img src="https://img.shields.io/badge/Buy_Me_A_Coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black" height=30></a>
32
26
  </p>
33
27
 
34
28
  ## Installation
@@ -113,9 +107,10 @@ print(JDKSObject.getObject())
113
107
  ```
114
108
  ---
115
109
 
116
- ### JSON_DUPLICATE_KEYS.get(`name`, `separator`="||", `parse_index`="$", `_isDebug_`=False)
110
+ ### JSON_DUPLICATE_KEYS.get(`name`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `_isDebug_`=False)
117
111
  _Get value in the JSON object by `name`_
118
112
  - `name`: the key name of the JSON object. Supported flatten key name format
113
+ - `case_insensitive`: the key name case (in)sensitive
119
114
  - `separator`:
120
115
  - `parse_index`:
121
116
  - `_isDebug_`: Show/ Hide debug error messages
@@ -137,10 +132,11 @@ print(JDKSObject.get("snapshot||author"))
137
132
  ```
138
133
  ---
139
134
 
140
- ### JSON_DUPLICATE_KEYS.set(`name`, `value`, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `_isDebug_`=False)
135
+ ### JSON_DUPLICATE_KEYS.set(`name`, `value`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `_isDebug_`=False)
141
136
  _Set a new `name` and `value` for the JSON object_
142
137
  - `name`: new key name for the JSON object. Supported flat key name format
143
138
  - `value`: value for key `name`
139
+ - `case_insensitive`: the key name case (in)sensitive
144
140
  - `separator`:
145
141
  - `parse_index`:
146
142
  - `dupSign_start`:
@@ -201,10 +197,11 @@ print(JDKSObject.getObject())
201
197
  ```
202
198
  ---
203
199
 
204
- ### JSON_DUPLICATE_KEYS.update(`name`, `value`, `separator`="||", `parse_index`="$", `_isDebug_`=False)
200
+ ### JSON_DUPLICATE_KEYS.update(`name`, `value`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `_isDebug_`=False)
205
201
  _Update new `value` for existing `name` in the JSON object_
206
202
  - `name`: the key name of the JSON object. Supported flatten key name format
207
203
  - `value`: new value for key `name`
204
+ - `case_insensitive`: the key name case (in)sensitive
208
205
  - `separator`:
209
206
  - `parse_index`:
210
207
  - `_isDebug_`: Show/ Hide debug error messages
@@ -226,9 +223,10 @@ print(JDKSObject.getObject())
226
223
  ```
227
224
  ---
228
225
 
229
- ### JSON_DUPLICATE_KEYS.delete(`name`, `separator`="||", `parse_index`="$", `_isDebug_`=False)
226
+ ### JSON_DUPLICATE_KEYS.delete(`name`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `_isDebug_`=False)
230
227
  _Delete a key-value pair in a JSON object by key `name`_
231
228
  - `name`: the key name of the JSON object. Supported flatten key name format
229
+ - `case_insensitive`: the key name case (in)sensitive
232
230
  - `separator`:
233
231
  - `parse_index`:
234
232
  - `_isDebug_`: Show/ Hide debug error messages
@@ -395,6 +393,9 @@ print(JDKSObject.getObject())
395
393
  ---
396
394
 
397
395
  ## CHANGELOG
396
+ #### [json-duplicate-keys v2024.11.19](https://github.com/truocphan/json-duplicate-keys/tree/2024.11.19)
397
+ - **Updated**: Allows getting (`JSON_DUPLICATE_KEYS.get`), setting (`JSON_DUPLICATE_KEYS.set`), updating (`JSON_DUPLICATE_KEYS.update`), deleting (`JSON_DUPLICATE_KEYS.delete`) JSON_DUPLICATE_KEYS objects with case-insensitive key names
398
+
398
399
  #### [json-duplicate-keys v2024.7.17](https://github.com/truocphan/json-duplicate-keys/tree/2024.7.17)
399
400
  - **Fixed**: issue [#3](https://github.com/truocphan/json-duplicate-keys/issues/3) break the set function when the key's value is empty. Thanks [ptth222](https://github.com/ptth222) for reporting this issue.
400
401
 
@@ -0,0 +1,6 @@
1
+ json_duplicate_keys/__init__.py,SHA256=K9bg6uSaRnP4JNorn0Y_Chw_ZnRIZoIU0RGxqHFk8-s,26545
2
+ json_duplicate_keys-2024.11.19.dist-info/LICENSE,SHA256=_hudSGMciUc27wGR8EMKfeb3atJRlf6rbhJtLnel-nc,1093
3
+ json_duplicate_keys-2024.11.19.dist-info/METADATA,SHA256=ytf0YHsh6CsnhIZdaihik1ibZkabt6J1QsHkhbpAlno,17673
4
+ json_duplicate_keys-2024.11.19.dist-info/WHEEL,SHA256=1VPi6hfNQaRRNuEdK_3dv9o8COtLGnHWJghhj4CQ28k,92
5
+ json_duplicate_keys-2024.11.19.dist-info/top_level.txt,SHA256=vdsGrPLVS_l-BFL1i4hCJBY5_-gq4Cwp-11yegA750Y,20
6
+ json_duplicate_keys-2024.11.19.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- json_duplicate_keys/__init__.py,SHA256=5RW69Kmsa6cKAifXRzATwU5dBa-ulzVY9pBUEb7nRe0,29951
2
- json_duplicate_keys-2024.7.17.dist-info/LICENSE,SHA256=_hudSGMciUc27wGR8EMKfeb3atJRlf6rbhJtLnel-nc,1093
3
- json_duplicate_keys-2024.7.17.dist-info/METADATA,SHA256=NB-7fKagSVyf32CJpIGgVD2mksXOmtzv07wYC0dCfE4,18108
4
- json_duplicate_keys-2024.7.17.dist-info/WHEEL,SHA256=1VPi6hfNQaRRNuEdK_3dv9o8COtLGnHWJghhj4CQ28k,92
5
- json_duplicate_keys-2024.7.17.dist-info/top_level.txt,SHA256=vdsGrPLVS_l-BFL1i4hCJBY5_-gq4Cwp-11yegA750Y,20
6
- json_duplicate_keys-2024.7.17.dist-info/RECORD,,