# coding=utf-8
# generate Exchange Server Protocols Master Property List.
# input text file source : https://interoperability.blob.core.windows.net/files/MS-OXPROPS/[MS-OXPROPS].pdf
# protocol version: 22.0
# protocol Date: 10/1/2018
import json
import os
txt_file_path = "ms_exchange_props.txt"
json_file_path = "ms_props_master.json"
id_map_file_path = "ms_props_id_map_autogenerated.py"
data_type_map_file_path = "ms_props_date_type_map.py"
python_file_header = """# coding=utf-8
# autogenerated using ms_props_generator.py\n\n"""
def generate_master_properties():
if not os.path.exists(txt_file_path):
return None
with open(txt_file_path, "r") as _file:
file_content = _file.read()
file_records = file_content.split("\n\n")
master_map = {
"list_name": "Exchange Server Protocols Master Property List",
"reference": "https://msdn.microsoft.com/en-us/library/cc433490(v=exchg.80).aspx",
}
properties_list = []
for record in file_records:
record_lines = record.splitlines()
record_map = {}
for line in record_lines:
if ":" in line:
try:
key, value = line.split(":", 2)
value = value.strip()
key = key.strip()
# change key name for Long Id
if key == "Property long ID (LID)":
key = "Property long ID"
# format canonical naming
if value.startswith("PidTag"):
record_map["name"] = value.replace("PidTag", "").strip()
record_map["canonical_type"] = "PidTag"
if value.startswith("PidLid"):
record_map["name"] = value.replace("PidLid", "").strip()
record_map["canonical_type"] = "PidLid"
if value.startswith("PidName"):
record_map["name"] = value.replace("PidName", "").strip()
record_map["canonical_type"] = "PidName"
# format entry data type
if key == "Data type":
name, code = value.split(",", 1)
record_map["data_type_name"] = name.strip()
record_map["data_type"] = code.strip()
else:
key = key.replace(" ", "_").lower().strip()
record_map[key] = value.strip()
except Exception as exp:
print(str(exp) + " " + line)
continue
if record_map:
properties_list.append(record_map)
if properties_list:
master_map["properties_list"] = properties_list
with open(json_file_path, "wb+") as json_file:
json_file.write(json.dumps(master_map, sort_keys=True, indent=4))
return master_map
def generate_id_name_mapping(master_map):
if not master_map:
return None
properties_list = master_map.get("properties_list")
id_map = {}
for prop in properties_list:
if "property_id" in prop:
id_map[prop["property_id"]] = {
"name": prop["name"],
"data_type": prop["data_type"],
}
if id_map:
with open(id_map_file_path, "wb+") as py_file:
py_file.write(python_file_header)
py_file.write(
"PROPS_ID_MAP = {}".format(json.dumps(id_map, sort_keys=True, indent=4))
)
return id_map
def generate_data_id_type_mapping(master_map):
if not master_map:
return None
properties_list = master_map.get("properties_list")
id_map = {}
for prop in properties_list:
if "data_type" in prop:
id_map[prop["data_type"]] = prop["data_type_name"]
if id_map:
with open(data_type_map_file_path, "wb+") as py_file:
py_file.write(python_file_header)
py_file.write(
"DATA_TYPE_MAP = {}".format(
json.dumps(id_map, sort_keys=True, indent=4)
)
)
return id_map
if __name__ == "__main__":
master_map_results = generate_master_properties()
id_map_results = generate_id_name_mapping(master_map_results)
data_type_map_results = generate_data_id_type_mapping(master_map_results)