diff --git a/unshackle/services/Netflix/__init__.py b/unshackle/services/Netflix/__init__.py index 68e87a1..923fe21 100644 --- a/unshackle/services/Netflix/__init__.py +++ b/unshackle/services/Netflix/__init__.py @@ -708,20 +708,44 @@ class Netflix(Service): def get_esn(self): if self.cdm.device_type == DeviceTypes.ANDROID: try: - # Use ESN map from config.yaml instead of generating a new one - esn = self.config["esn_map"][self.cdm.system_id] + esn_template = self.config["esn_map"][self.cdm.system_id] except KeyError: self.log.error(f"ESN mapping not found for system_id: {self.cdm.system_id}") raise Exception(f"ESN mapping not found for system_id: {self.cdm.system_id}") - esn_value = { - 'esn': esn, - 'type': self.cdm.device_type - } cached_esn = self.esn.data.get("esn") if isinstance(self.esn.data, dict) else self.esn.data cached_type = self.esn.data.get("type") if isinstance(self.esn.data, dict) else None - if cached_esn != esn or cached_type != DeviceTypes.ANDROID or (hasattr(self.esn, "expired") and self.esn.expired): - self.esn.set(esn_value, expiration=1 * 60 * 60) + cache_expired = hasattr(self.esn, "expired") and self.esn.expired + randomchar_pattern = r"\{randomchar_(\d+)\}" + + if re.search(randomchar_pattern, esn_template): + esn_regex = "^" + re.sub( + r"\\\{randomchar_(\d+)\\\}", + lambda match: rf"[A-Z0-9]{{{match.group(1)}}}", + re.escape(esn_template) + ) + "$" + + if cached_type == DeviceTypes.ANDROID and isinstance(cached_esn, str) and re.match(esn_regex, cached_esn) and not cache_expired: + esn = cached_esn + else: + self.log.info("Generating Android ESN from configured randomchar template") + esn = re.sub( + randomchar_pattern, + lambda match: "".join(random.choice("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ") for _ in range(int(match.group(1)))), + esn_template + ) + self.esn.set({ + 'esn': esn, + 'type': self.cdm.device_type + }, expiration=1 * 60 * 60) + else: + esn = esn_template + esn_value = { + 'esn': esn, + 'type': self.cdm.device_type + } + if cached_esn != esn or cached_type != DeviceTypes.ANDROID or cache_expired: + self.esn.set(esn_value, expiration=1 * 60 * 60) else: ESN_GEN = "".join(random.choice("0123456789ABCDEF") for _ in range(30)) generated_esn = f"NFCDIE-03-{ESN_GEN}" diff --git a/unshackle/services/Netflix/config.yaml b/unshackle/services/Netflix/config.yaml index 712e045..204ccfd 100644 --- a/unshackle/services/Netflix/config.yaml +++ b/unshackle/services/Netflix/config.yaml @@ -22,7 +22,7 @@ esn_map: 8131: "HISETVK84500000000000000000000000007401422" 22590: "NFANDROID1-PXA-P-L3-XIAOMM2102J20SG-22590-020NTB086HJPGG70MDDMR0306MR0NNO5G3DJGFCKS9HJF58ER9QA21VFG4I0246JRN6TF16L9I627EPK708SH42UUMG1ASFVG20F3" 12063: "NFANDROID1-PRV-P-SHENZHENKTC-49B1U-12063-2PAENERYJWY35H7F24163TMUCBBA4VRHQ2XZX4OBU4MUTKYFW50BMFBVGTUMN6IM0" - 7110: "NFANDROID1-PRV-P-MSD6886602GUHDANDROIDTV-HISENHISMARTTV-A4-7110-5EAE417AE3DB234B5FFC4EFC289A1B11D4475CC5949186C83F4C3D20FF203972" + 7110: "NFANDROID1-PRV-P-MSD6886602GUHDANDROIDTV-HISENHISMARTTV-A4-7110-{randomchar_64}" 16401: "NFANDROID1-PRV-P-MSD6886602GUHDANDROIDTV-HISENHISMARTTV-A4-16401-FA2CF15C2E3A00BDDC3B6811C210893F0CD2C062471A62C2A0DD8C28BAE8DF42" endpoints: website: "https://www.netflix.com/nq/website/memberapi/{build_id}/pathEvaluator"