202 lines
6.0 KiB
Python
202 lines
6.0 KiB
Python
from dataclasses import dataclass
|
|
|
|
import eaapi
|
|
|
|
|
|
class Model:
|
|
def __init__(self, gamecode: str, dest: str, spec: str, rev: str, datecode: str):
|
|
self._gamecode = gamecode
|
|
self._dest = dest
|
|
self._spec = spec
|
|
self._rev = rev
|
|
self._datecode = datecode
|
|
|
|
@classmethod
|
|
def from_model_str(cls, model: str) -> "Model":
|
|
return cls(*eaapi.parse_model(model))
|
|
|
|
@property
|
|
def gamecode(self):
|
|
return self._gamecode
|
|
|
|
@property
|
|
def dest(self):
|
|
return self._dest
|
|
|
|
@property
|
|
def spec(self):
|
|
return self._spec
|
|
|
|
@property
|
|
def rev(self):
|
|
return self._rev
|
|
|
|
@property
|
|
def datecode(self):
|
|
return int(self._datecode)
|
|
|
|
@property
|
|
def year(self):
|
|
return int(self._datecode[:4])
|
|
|
|
@property
|
|
def month(self):
|
|
return int(self._datecode[4:6])
|
|
|
|
@property
|
|
def day(self):
|
|
return int(self._datecode[6:8])
|
|
|
|
@property
|
|
def minor(self):
|
|
return int(self._datecode[8:10])
|
|
|
|
def __hash__(self):
|
|
return hash(str(self))
|
|
|
|
def __eq__(self, other):
|
|
if not isinstance(other, Model):
|
|
return False
|
|
return str(other) == str(self)
|
|
|
|
def __str__(self):
|
|
return f"{self.gamecode}:{self.dest}:{self.spec}:{self.rev}:{self.datecode}"
|
|
|
|
def __repr__(self):
|
|
return f"<Model {self} at 0x{id(self):016X}>"
|
|
|
|
|
|
@dataclass
|
|
class DatecodeMatcher:
|
|
year: int | None = None
|
|
month: int | None = None
|
|
day: int | None = None
|
|
minor: int | None = None
|
|
|
|
@classmethod
|
|
def from_str(cls, datecode: str):
|
|
if len(datecode) != 10 or not datecode.isdigit():
|
|
raise ValueError("Not a valid datecode")
|
|
return cls(
|
|
int(datecode[0:4]),
|
|
int(datecode[4:6]),
|
|
int(datecode[6:8]),
|
|
int(datecode[8:10])
|
|
)
|
|
|
|
def _num_filters(self):
|
|
num = 0
|
|
if self.year is not None:
|
|
num += 1
|
|
if self.month is not None:
|
|
num += 1
|
|
if self.day is not None:
|
|
num += 1
|
|
if self.minor is not None:
|
|
num += 1
|
|
return num
|
|
|
|
def __lt__(self, other):
|
|
if self._num_filters() < other._num_filters():
|
|
return False
|
|
if self.minor is None and other.minor is not None:
|
|
return False
|
|
if self.day is None and other.day is not None:
|
|
return False
|
|
if self.month is None and other.month is not None:
|
|
return False
|
|
if self.year is None and other.year is not None:
|
|
return False
|
|
return True
|
|
|
|
def __hash__(self):
|
|
return hash(str(self))
|
|
|
|
def __str__(self):
|
|
year = self.year if self.year is not None else "----"
|
|
month = self.month if self.month is not None else "--"
|
|
day = self.day if self.day is not None else "--"
|
|
minor = self.minor if self.minor is not None else "--"
|
|
return f"{year:04}{month:02}{day:02}{minor:02}"
|
|
|
|
def matches(self, model):
|
|
if self.year is not None and model.year != self.year:
|
|
return False
|
|
if self.month is not None and model.month != self.month:
|
|
return False
|
|
if self.day is not None and model.day != self.day:
|
|
return False
|
|
if self.minor is not None and model.minor != self.minor:
|
|
return False
|
|
return True
|
|
|
|
|
|
@dataclass
|
|
class ModelMatcher:
|
|
gamecode: str | None = None
|
|
dest: str | None = None
|
|
spec: str | None = None
|
|
rev: str | None = None
|
|
datecode: list[DatecodeMatcher] | DatecodeMatcher | None = None
|
|
|
|
def _num_filters(self):
|
|
num = 0
|
|
if self.gamecode is not None:
|
|
num += 1
|
|
if self.dest is not None:
|
|
num += 1
|
|
if self.spec is not None:
|
|
num += 1
|
|
if self.rev is not None:
|
|
num += 1
|
|
if isinstance(self.datecode, list):
|
|
num += sum(i._num_filters() for i in self.datecode)
|
|
elif self.datecode is not None:
|
|
num += self.datecode._num_filters()
|
|
return num
|
|
|
|
def __lt__(self, other):
|
|
if self._num_filters() < other._num_filters():
|
|
return False
|
|
if self.datecode is None and other.datecode is not None:
|
|
return False
|
|
if self.rev is None and other.rev is not None:
|
|
return False
|
|
if self.spec is None and other.spec is not None:
|
|
return False
|
|
if self.dest is None and other.dest is not None:
|
|
return False
|
|
if self.gamecode is None and other.gamecode is not None:
|
|
return False
|
|
return True
|
|
|
|
def __hash__(self):
|
|
return hash(str(self))
|
|
|
|
def __str__(self):
|
|
gamecode = self.gamecode if self.gamecode is not None else "---"
|
|
dest = self.dest if self.dest is not None else "-"
|
|
spec = self.spec if self.spec is not None else "-"
|
|
rev = self.rev if self.rev is not None else "-"
|
|
datecode = self.datecode if self.datecode is not None else "-" * 10
|
|
if isinstance(self.datecode, list):
|
|
datecode = "/".join(str(i) for i in self.datecode)
|
|
if not datecode:
|
|
datecode = "-" * 10
|
|
return f"{gamecode:3}:{dest}:{spec}:{rev}:{datecode}"
|
|
|
|
def matches(self, model):
|
|
if self.gamecode is not None and model.gamecode != self.gamecode:
|
|
return False
|
|
if self.dest is not None and model.dest != self.dest:
|
|
return False
|
|
if self.spec is not None and model.spec != self.spec:
|
|
return False
|
|
if self.rev is not None and model.rev != self.rev:
|
|
return False
|
|
if isinstance(self.datecode, list):
|
|
return any(i.matches(model) for i in self.datecode)
|
|
if self.datecode is not None:
|
|
return self.datecode.matches(model)
|
|
return True
|