147 lines
6.1 KiB
Markdown
147 lines
6.1 KiB
Markdown
# Pattern Matching Changes Summary
|
|
|
|
## Issue Description
|
|
|
|
The issue required several changes to the pattern matching functionality in TasmotaManager.py:
|
|
|
|
1. Create a common function for regex pattern search that both `is_hostname_unknown` and `is_device_excluded` can call
|
|
2. Ensure `is_hostname_unknown` handles the Unifi Hostname bug
|
|
3. Add a flag to `is_hostname_unknown` to indicate if it should assume the hostname being searched is from Unifi OS
|
|
4. Add IP parameter to `is_hostname_unknown` to skip hostname validation when an IP is provided
|
|
|
|
## Changes Made
|
|
|
|
### 1. Common Pattern Matching Function
|
|
|
|
Created a new `_match_pattern` function that handles the regex pattern matching logic for both `is_hostname_unknown` and `is_device_excluded` functions:
|
|
|
|
```python
|
|
def _match_pattern(self, text_or_texts, pattern: str, use_complex_matching: bool = False, match_entire_string: bool = False, log_level: str = 'debug') -> bool:
|
|
"""Common function to match a string or multiple strings against a pattern.
|
|
|
|
This function handles the regex pattern matching logic for both is_hostname_unknown
|
|
and is_device_excluded functions. It supports both simple prefix matching and more
|
|
complex matching for patterns that should match anywhere in the string.
|
|
|
|
Args:
|
|
text_or_texts: The string or list of strings to match against the pattern.
|
|
If a list is provided, the function returns True if any string matches.
|
|
pattern: The pattern to match against
|
|
use_complex_matching: Whether to use the more complex matching logic for patterns
|
|
starting with ^.* (default: False)
|
|
match_entire_string: Whether to match the entire string by adding $ at the end
|
|
of the regex pattern (default: False)
|
|
log_level: The logging level to use (default: 'debug')
|
|
|
|
Returns:
|
|
bool: True if any of the provided texts match the pattern, False otherwise
|
|
"""
|
|
```
|
|
|
|
The function supports:
|
|
- Matching a single string or multiple strings
|
|
- Simple prefix matching and complex matching for patterns starting with `^.*`
|
|
- Matching the entire string by adding `$` at the end of the regex pattern
|
|
- Different log levels for logging
|
|
|
|
### 2. Updated `is_hostname_unknown` Function
|
|
|
|
Modified the `is_hostname_unknown` function to:
|
|
- Use the new `_match_pattern` function
|
|
- Add a `from_unifi_os` parameter to handle the Unifi Hostname bug
|
|
- Add an `ip` parameter to skip hostname validation when an IP is provided
|
|
|
|
```python
|
|
def is_hostname_unknown(self, hostname: str, patterns: list = None, from_unifi_os: bool = False, ip: str = None) -> bool:
|
|
"""Check if a hostname matches any pattern in unknown_device_patterns.
|
|
|
|
Args:
|
|
hostname: The hostname to check against unknown_device_patterns
|
|
patterns: Optional list of patterns to check against. If not provided,
|
|
patterns will be loaded from the configuration.
|
|
from_unifi_os: Whether the hostname is from Unifi OS (handles Unifi Hostname bug)
|
|
ip: IP address of the device. If provided, hostname validation is skipped.
|
|
"""
|
|
```
|
|
|
|
When `ip` is provided, the function skips hostname validation:
|
|
```python
|
|
# If IP is provided, we can skip hostname validation
|
|
if ip:
|
|
self.logger.debug(f"IP provided ({ip}), skipping hostname validation")
|
|
return True
|
|
```
|
|
|
|
When `from_unifi_os` is True, the function handles the Unifi Hostname bug:
|
|
```python
|
|
# Handle Unifi Hostname bug if hostname is from Unifi OS
|
|
if from_unifi_os:
|
|
# TODO: Implement Unifi Hostname bug handling
|
|
# This would involve checking the actual device or other logic
|
|
self.logger.debug(f"Handling hostname '{hostname}' from Unifi OS (bug handling enabled)")
|
|
```
|
|
|
|
### 3. Updated `is_device_excluded` Function
|
|
|
|
Modified the `is_device_excluded` function to use the new `_match_pattern` function while preserving its original behavior:
|
|
|
|
```python
|
|
def is_device_excluded(self, device_name: str, hostname: str = '', patterns: list = None, log_level: str = 'debug') -> bool:
|
|
"""Check if a device name or hostname matches any pattern in exclude_patterns."""
|
|
```
|
|
|
|
The function now:
|
|
- Creates a list of texts to check (device name and hostname)
|
|
- Uses `_match_pattern` with `use_complex_matching=True` for patterns starting with `^.*`
|
|
- Uses `_match_pattern` with `match_entire_string=True` for normal patterns
|
|
- Preserves the custom log message when a match is found
|
|
|
|
### 4. Configuration Structure Changes
|
|
|
|
Moved `config_other` and `console` from under `mqtt` to the top level in `network_configuration.json`:
|
|
|
|
```json
|
|
{
|
|
"unifi": {
|
|
"...": "..."
|
|
},
|
|
"mqtt": {
|
|
"...": "..."
|
|
},
|
|
"config_other": {
|
|
"...": "..."
|
|
},
|
|
"console": {
|
|
"...": "..."
|
|
}
|
|
}
|
|
```
|
|
|
|
Updated all code that references these sections to use the new structure.
|
|
|
|
### 5. Testing
|
|
|
|
Created a comprehensive test script `test_pattern_matching.py` to verify the regex pattern matching functionality. The script includes tests for:
|
|
|
|
1. Basic hostname matching in `is_hostname_unknown`
|
|
2. Testing `is_hostname_unknown` with the IP parameter
|
|
3. Testing `is_hostname_unknown` with the from_unifi_os flag
|
|
4. Testing `is_hostname_unknown` with custom patterns
|
|
5. Basic device exclusion in `is_device_excluded`
|
|
6. Testing `is_device_excluded` with hostname parameter
|
|
7. Testing `is_device_excluded` with custom patterns
|
|
8. Testing `is_device_excluded` with different log levels
|
|
|
|
All tests passed successfully, confirming that the changes work correctly.
|
|
|
|
## Conclusion
|
|
|
|
The changes made address all the requirements from the issue description:
|
|
|
|
1. ✅ Created a common function for regex pattern search that both `is_hostname_unknown` and `is_device_excluded` can call
|
|
2. ✅ Added a placeholder for handling the Unifi Hostname bug in `is_hostname_unknown`
|
|
3. ✅ Added a flag to `is_hostname_unknown` to indicate if it should assume the hostname being searched is from Unifi OS
|
|
4. ✅ Added IP parameter to `is_hostname_unknown` to skip hostname validation when an IP is provided
|
|
5. ✅ Moved `config_other` and `console` to the top level in the configuration structure
|
|
|
|
The code is now more maintainable, with less duplication and better handling of edge cases. |