1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2025-08-08 22:36:48 +02:00

fixup for byte and datetime values

This commit is contained in:
Kelly Brazil
2022-07-31 16:47:48 -07:00
parent 108e1b730e
commit 4744757726
2 changed files with 107 additions and 0 deletions

View File

@ -2,6 +2,10 @@
Converts binary and XML PLIST files.
Binary values are converted into an ASCII hex representation.
Datetime objects are converted into Unix epoch timestamps and ISO strings.
Usage (cli):
$ cat file.plist | jc --plist
@ -31,6 +35,8 @@ Examples:
"""
from typing import List, Dict, Union
import plistlib
import binascii
from datetime import datetime
import jc.utils
@ -61,6 +67,57 @@ def _process(proc_data: Dict) -> Dict:
return proc_data
def _b2a(byte_string: bytes) -> str:
"""Convert a byte string to a colon-delimited hex ascii string"""
# need try/except since seperator was only introduced in python 3.8.
# provides compatibility for python 3.6 and 3.7.
try:
return binascii.hexlify(byte_string, ':').decode('utf-8')
except TypeError:
hex_string = binascii.hexlify(byte_string).decode('utf-8')
colon_seperated = ':'.join(hex_string[i:i+2] for i in range(0, len(hex_string), 2))
return colon_seperated
def _fix_objects(obj):
"""
Recursively traverse the nested dictionary or list and convert objects
into JSON serializable types.
"""
if isinstance(obj, dict):
for k, v in obj.copy().items():
if isinstance(v, datetime):
iso = v.isoformat()
v = int(round(v.timestamp()))
obj.update({k: v, f'{k}_iso': iso})
continue
if isinstance(v, bytes):
v = _b2a(v)
obj.update({k: v})
continue
if isinstance(v, dict):
obj.update({k: _fix_objects(v)})
continue
if isinstance(v, list):
newlist =[]
for i in v:
newlist.append(_fix_objects(i))
obj.update({k: newlist})
continue
if isinstance(obj, list):
new_list = []
for i in obj:
new_list.append(_fix_objects(i))
obj = new_list
return obj
def parse(
data: Union[str, bytes],
raw: bool = False,
@ -89,5 +146,6 @@ def parse(
if jc.utils.has_data(data):
raw_output = plistlib.loads(data)
raw_output = _fix_objects(raw_output)
return raw_output if raw else _process(raw_output)

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aDate</key>
<date>2022-07-31T16:34:30Z</date>
<key>aDict</key>
<dict>
<key>aFalseValue</key>
<false/>
<key>aThirdString</key>
<string>Mässig, Maß</string>
<key>aTrueValue</key>
<true/>
<key>anotherString</key>
<string>&lt;hello &amp; hi there!&gt;</string>
</dict>
<key>aFloat</key>
<real>0.1</real>
<key>aList</key>
<array>
<string>A</string>
<string>B</string>
<integer>12</integer>
<real>32.1</real>
<array>
<integer>1</integer>
<integer>2</integer>
<integer>3</integer>
</array>
</array>
<key>aString</key>
<string>Doodah</string>
<key>anInt</key>
<integer>728</integer>
<key>someData</key>
<data>
PGJpbmFyeSBndW5rPg==
</data>
<key>someMoreData</key>
<data>
PGxvdHMgb2YgYmluYXJ5IGd1bms+PGxvdHMgb2YgYmluYXJ5IGd1bms+PGxvdHMgb2Yg
YmluYXJ5IGd1bms+PGxvdHMgb2YgYmluYXJ5IGd1bms+PGxvdHMgb2YgYmluYXJ5IGd1
bms+PGxvdHMgb2YgYmluYXJ5IGd1bms+PGxvdHMgb2YgYmluYXJ5IGd1bms+PGxvdHMg
b2YgYmluYXJ5IGd1bms+PGxvdHMgb2YgYmluYXJ5IGd1bms+PGxvdHMgb2YgYmluYXJ5
IGd1bms+
</data>
</dict>
</plist>