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