# 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)