1from fnmatch import fnmatch
  2
  3from chart.events.eventclass import EventClass
  4from chart.db.model.table import TableInfo
  5
  6
  7def do_search(any_field=None,
  8              name=None,
  9              description=None,
 10              unit=None,
 11              source=None,
 12              sid_name=None):
 13    """
 14    Search for events and parameters
 15    :param any_regex: Regular expression that will match name, description or unit
 16    :param name_regex: Regular expression that will match name
 17    :param description_regex: Regular expression that will match description
 18    :param unit_regex: Regular expression that will match unit
 19    :return: Event class matches and parameter matches
 20    """
 21
 22    name_regex, description_regex, unit_regex, source_regex = None, None, None, None
 23
 24    if any_field is not None:
 25        name_regex = "*" + any_field.upper().strip() + "*"
 26        description_regex = "*" + any_field.upper().strip() + "*"
 27        unit_regex = "*" + any_field.upper().strip() + "*"
 28        source_regex = "*" + any_field.upper().strip() + "*"
 29    if name is not None:
 30        name_regex = "*" + name.upper().strip() + "*"
 31    if description is not None:
 32        description_regex = "*" + description.upper().strip() + "*"
 33    if unit is not None:
 34        unit_regex = "*" + unit.upper().strip() + "*"
 35    if source is not None:
 36        source_regex = "*" + source.upper().strip() + "*"
 37
 38    parameter_matches_dict = {}
 39
 40    parameter_matches = []
 41    event_class_matches = []
 42    event_property_matches = []
 43
 44    # Match events
 45    for event_class in EventClass.all():
 46        name = event_class.name
 47        description = event_class.description
 48
 49        match = False
 50
 51        if name_regex:
 52            if fnmatch(name.upper(), name_regex):
 53                match = True
 54
 55        if description_regex and description is not None:
 56            if fnmatch(description.upper(), description_regex):
 57                match = True
 58
 59        if match:
 60            event_class_matches.append({
 61                "label": name,
 62                "description": description,
 63                "data": "EVENT" + "." + name,
 64                "leaf": True,
 65                "icon": "pi pi-chart-bar"
 66            })
 67
 68        # Match event properties
 69        for prop_name, prop in event_class.instance_properties.items():
 70            match = False
 71            description = prop.get("description")
 72            unit = prop.get("unit")
 73
 74            match = False
 75
 76            if name_regex:
 77                if fnmatch(prop_name.upper(), name_regex):
 78                    match = True
 79
 80            if description_regex and description is not None:
 81                if fnmatch(description.upper(), description_regex):
 82                    match = True
 83
 84            if unit_regex and unit is not None:
 85                if fnmatch(unit.upper(), unit_regex):
 86                    match = True
 87
 88            elif match:
 89                event_property_matches.append({
 90                    "label": event_class.name + "." + prop_name + (f" ({unit})" if unit else ""),
 91                    "data": "EVENT" + "." + event_class.name + "." + "." + prop_name,
 92                    "description": description,
 93                    "leaf": True,
 94                    "icon": "pi pi-chart-line"
 95                })
 96
 97    # Match parameters
 98    for table in [TableInfo.all(visible=True)][0][sid_name]:
 99        for field, field_info in table.fields.items():
100            name = field_info.name
101            description = field_info.description
102            unit = field_info.unit
103
104            match = False
105
106            if name_regex:
107                if fnmatch(name.upper(), name_regex):
108                    match = True
109
110            if description_regex and description is not None:
111                if fnmatch(description.upper(), description_regex):
112                    match = True
113
114            if unit_regex and unit is not None:
115                if fnmatch(unit.upper(), unit_regex):
116                    match = True
117
118            if source_regex:
119                if fnmatch(table.name.upper(), source_regex):
120                    match = True
121
122            # Same parameter should be listed only once in search results
123            # All sources for parameter will be listed
124            if match:
125                if not name in parameter_matches_dict:
126                    param_node = {
127                        "label": name + (f" ({unit})" if unit else ""),
128                        "data": name,
129                        "description": description,
130                        "leaf": False,
131                        "expandedIcon": "pi pi-folder",
132                        "collapsedIcon": "pi pi-folder",
133                        "children": []
134                    }
135
136                    parameter_matches.append(param_node)
137                    parameter_matches_dict[name] = param_node
138
139                parameter_matches_dict[name]["children"].append({
140                    "label": table.name + "." + name + (f" ({unit})" if unit else ""),
141                    "data": table.name + "." + name,
142                    "description": description,
143                    "has_choices": field_info.choices != None,
144                    "leaf": True,
145                    "icon": "pi pi-chart-line"
146                })
147
148    return [
149        {
150            "label": "Events",
151            "data": "EVENTS",
152            "leaf": False,
153            "expandedIcon": "pi pi-folder",
154            "collapsedIcon": "pi pi-folder",
155            "children": event_class_matches,
156            "expanded": True
157        },
158        {
159            "label": "Event Properties",
160            "data": "EVENT_PROPERTIES",
161            "leaf": False,
162            "expandedIcon": "pi pi-folder",
163            "collapsedIcon": "pi pi-folder",
164            "children": event_property_matches,
165            "expanded": True
166        },
167        {
168            "label": "Parameters",
169            "data": "PARAMETERS",
170            "leaf": False,
171            "expandedIcon": "pi pi-folder",
172            "collapsedIcon": "pi pi-folder",
173            "children": parameter_matches,
174            "expanded": True
175        }
176    ]