Compare test suites results feature PRODX-36767

Update Django to 4.2 version

Change-Id: Ieed17cfac12518262503043ccee03473a3023221
diff --git a/testrail_bot/control/utils.py b/testrail_bot/control/utils.py
new file mode 100644
index 0000000..2dabafe
--- /dev/null
+++ b/testrail_bot/control/utils.py
@@ -0,0 +1,57 @@
+from parse import parse
+from typing import Dict, List
+
+
+def parse_title(test_name):
+    # Sometimes id can be without the closing ] symbol
+    if "[" in test_name and "]" not in test_name:
+        test_name += "]"
+    token_count = test_name.split(".").__len__()
+
+    if test_name.startswith("=="):
+        return test_name
+
+    if test_name.startswith(".setUp") or test_name.startswith(".tearDown"):
+        fmt = "{test_title}(" + "{}." * (token_count - 2) + "{class_name})"
+        r = parse(fmt, test_name)
+        return f"{r['class_name']}.{r['test_title']}".strip()
+    try:
+        fmt = "{}." * (token_count - 2) + "{class_name}.{test_title}[{id}]"
+        r = parse(fmt, test_name)
+        return f"{r['test_title']}[{r['id']}]"
+    except TypeError:
+        # return file_name.test_class.test_name in other complicated cases
+        return '.'.join(test_name.split(".")[:3])
+
+
+def short_names_for_dict(_dict):
+    __dict = {}
+    for _k in _dict.keys():
+        __k = parse_title(_k)
+        # Replace only those keys which are absent in the dict or empty
+        # (defined as "No result found")
+        if __dict.get(__k) == "No result found" or not __dict.get(__k):
+            __dict[__k] = _dict[_k]
+    return __dict
+
+
+def get_dict_diff(dict1: dict,
+                  dict2: dict,
+                  compare_by_key=None) -> Dict[str, List]:
+    all_keys = sorted(set(list(dict1.keys()) + list(dict2.keys())))
+
+    result = dict()
+    for k in all_keys:
+        if compare_by_key:
+            if dict1.get(k, {}).get(compare_by_key) == dict2.get(k, {}).get(
+                    compare_by_key):
+                continue
+        else:
+            if dict1.get(k) == dict2.get(k):
+                continue
+        result[k] = [dict1.get(k), dict2.get(k)]
+    return result
+
+
+if __name__ == "__main__":
+    pass