|
| 1 | +import re |
| 2 | +from dataclasses import dataclass |
| 3 | + |
| 4 | + |
| 5 | +@dataclass |
| 6 | +class Beamline: |
| 7 | + dom: str |
| 8 | + desc: str |
| 9 | + |
| 10 | + |
| 11 | +@dataclass |
| 12 | +class Entry: |
| 13 | + type: str |
| 14 | + DESC: str |
| 15 | + P: str |
| 16 | + M: str | None |
| 17 | + R: str | None |
| 18 | + |
| 19 | + |
| 20 | +@dataclass |
| 21 | +class Component: |
| 22 | + name: str |
| 23 | + desc: str |
| 24 | + prefix: str |
| 25 | + filename: str | None = None |
| 26 | + |
| 27 | + def __post_init__(self): |
| 28 | + self._extract_p_and_r() |
| 29 | + |
| 30 | + def __repr__(self) -> str: |
| 31 | + return f"Component(name={self.name}, desc={self.desc}, \ |
| 32 | + prefix={self.P}, suffix={self.R}, filename={self.filename})" |
| 33 | + |
| 34 | + def _extract_p_and_r(self): |
| 35 | + pattern = re.compile( |
| 36 | + r""" |
| 37 | + ^ # start of string |
| 38 | + (?= # lookahead to ensure the following pattern matches |
| 39 | + [A-Za-z0-9-]{14,16} # match 14 to 16 alphanumeric characters or hyphens |
| 40 | + [:A-Za-z0-9]* # match zero or more colons or alphanumeric characters |
| 41 | + [.A-Za-z0-9] # match a dot or alphanumeric character |
| 42 | + ) |
| 43 | + (?!.*--) # negative lookahead to ensure no double hyphens |
| 44 | + (?!.*:\..) # negative lookahead to ensure no colon followed by a dot |
| 45 | + ( # start of capture group 1 |
| 46 | + (?:[A-Za-z0-9]{2,5}-){3} # match 2 to 5 alphanumeric characters followed |
| 47 | + # by a hyphen, repeated 3 times |
| 48 | + [\d]* # match zero or more digits |
| 49 | + [^:]? # match zero or one non-colon character |
| 50 | + ) |
| 51 | + (?::([a-zA-Z0-9:]*))? # match zero or one colon followed by zero or more |
| 52 | + # alphanumeric characters or colons (capture group 2) |
| 53 | + (?:\.([a-zA-Z0-9]+))? # match zero or one dot followed by one or more |
| 54 | + # alphanumeric characters (capture group 3) |
| 55 | + $ # end of string |
| 56 | + """, |
| 57 | + re.VERBOSE, |
| 58 | + ) |
| 59 | + |
| 60 | + match = re.match(pattern, self.prefix) |
| 61 | + if match: |
| 62 | + self.P: str = match.group(1) |
| 63 | + self.R: str = match.group(2) |
| 64 | + # TODO: Is this needed? |
| 65 | + self.attribute: str | None = match.group(3) |
| 66 | + else: |
| 67 | + raise AttributeError(f"No valid PV prefix found for {self.name}.") |
0 commit comments