Files
script.service.ultimate/lib/streaming_providers/providers/magenta2/constants.py
T
2026-06-15 13:41:18 +02:00

399 lines
14 KiB
Python

# streaming_providers/providers/magenta2/constants.py
# ============================================================================
# Magenta2 Configuration
# ============================================================================
# Supported countries (Magenta2 is Germany-specific)
SUPPORTED_COUNTRIES = ["de"]
# Default country
DEFAULT_COUNTRY = "de"
MAGENTA2_LOGO = "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/Magenta_TV_Logo_2024.svg/2339px-Magenta_TV_Logo_2024.svg.png"
# Platform configuration
DEFAULT_PLATFORM = "android-tv"
MAGENTA2_PLATFORMS = {
"web": {
"device_name": "Web Browser",
"firmware": "Chrome 120",
"user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"terminal_type": "WEB",
# TAA-specific device identification
"taa_device_model": "Web Browser",
"taa_os": "Chrome 120",
},
"android-tv": {
"device_name": "Android TV",
"firmware": "Android 11",
"user_agent": "Dalvik/2.1.0 (Linux; U; Android 11; SHIELD Android TV Build/RQ1A.210105.003) ((2.00T_ATV::3.134.4462::mdarcy::))",
"terminal_type": "ATV_ANDROIDTV",
# TAA-specific device identification (API level format required)
"taa_device_model": "SHIELD Android TV",
"taa_os": "API level 30",
},
"atv-launcher": {
"device_name": "MagentaTV Stick",
"firmware": "Android 11",
"user_agent": "Mozilla/5.0 (Linux; Android 11; AFTS Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",
"terminal_type": "ATV_LAUNCHER",
# TAA-specific device identification
"taa_device_model": "MagentaTV Stick",
"taa_os": "API level 30",
},
"android-mobile": {
"device_name": "Android Mobile",
"firmware": "Android 13",
"user_agent": "Mozilla/5.0 (Linux; Android 13; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Mobile Safari/537.36",
"terminal_type": "ANDROID_MOBILE",
# TAA-specific device identification
"taa_device_model": "Android Mobile",
"taa_os": "API level 33",
},
"ios": {
"device_name": "iPhone",
"firmware": "iOS 15",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1",
"terminal_type": "IOS",
# TAA-specific device identification
"taa_device_model": "iPhone",
"taa_os": "iOS 15.0",
},
}
# ============================================================================
# Manifest Request Configuration
# ============================================================================
# App identification for manifest requests
MAGENTA2_APP_NAME = "MagentaTV"
MAGENTA2_APP_VERSION = "104180"
MAGENTA2_RUNTIME_VERSION = "1"
# Model names for manifest requests (different from device models!)
MANIFEST_MODEL_MAPPINGS = {
"web": "DT:WEB",
"android-tv": "DT:ATV-AndroidTV",
"atv-launcher": "DT:ATV-Launcher",
"android-mobile": "DT:Android-Mobile",
"ios": "DT:IOS",
}
# Firmware strings for manifest requests
MANIFEST_FIRMWARE_MAPPINGS = {
"web": "Chrome 120",
"android-tv": "API level 30",
"atv-launcher": "API level 30",
"android-mobile": "API level 33",
"ios": "iOS 15.0",
}
# Also update the fallback mappings:
CLIENT_MODEL_MAPPINGS = {
"web": "ftv-web",
"android-tv": "ftv-androidtv",
"atv-launcher": "ftv-androidtv",
"android-mobile": "ftv-android",
"ios": "ftv-ios",
}
DEVICE_MODEL_MAPPINGS = {
"web": "WebBrowser_FTV",
"android-tv": "AndroidTV_FTV",
"atv-launcher": "AndroidTV_FTV",
"android-mobile": "AndroidMobile_FTV",
"ios": "iOS_FTV",
}
# And update subscriber types if needed:
SUBSCRIBER_TYPES = {
"web": "WEB_OTT_DT",
"android-tv": "FTV_OTT_DT",
"atv-launcher": "FTV_OTT_DT", # Same as android-tv
"android-mobile": "MOB_OTT_DT", # Different for mobile
"ios": "IOS_OTT_DT",
}
# ============================================================================
# API Configuration - MINIMAL HARDCODING
# ============================================================================
# Only bootstrap endpoint is hardcoded - everything else discovered dynamically
MAGENTA2_BASE_URL = "https://prod.dcm.telekom-dienste.de/v1"
MAGENTA2_BOOTSTRAP_URL = MAGENTA2_BASE_URL + "/settings/{terminal_type}/bootstrap"
MAGENTA2_MANIFEST_URL = MAGENTA2_BASE_URL + "/settings/{terminal_type}/manifest"
# Fallback endpoints if discovery fails
MAGENTA2_FALLBACK_ENDPOINTS = {
"OPENID_CONFIG": "https://accounts.login.idm.telekom.com/.well-known/openid-configuration",
"TAA_AUTH": "https://taa.p7s1.io/api/v1/taa",
"ENTITLEMENT": "https://entitlement.p7s1.io/api/user/entitlement-token",
}
# Emergency last-resort fallback ONLY — should never be reached in production
# since the account ID is extracted dynamically from the manifest's pvrBaseUrl.
# If this value is being used, it means both manifest and bootstrap discovery failed.
MAGENTA2_FALLBACK_ACCOUNT_URI = "http://access.auth.theplatform.com/data/Account/2709353023"
# ============================================================================
# Application Configuration
# ============================================================================
# Application identifiers
IDM = "TDGIDM"
APPVERSION2 = "3.134.4462"
SSO_URL = "https://ssom.magentatv.de/login"
# SSO User Agent
SSO_USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
# ============================================================================
# OAuth2 Configuration
# ============================================================================
# Client IDs for different platforms
MAGENTA2_CLIENT_IDS = {
"web": "709115c2-f87e-4bad-9b94-28ac08d72cd9",
"android-tv": "05f5f3df-1130-4707-a761-c04d0c50b7f2",
"ios": "21218403-52ec-4a65-abf4-f36a0eadd631",
}
# Client ID used for SMIL/selector manifest requests
SMIL_CLIENT_ID = "a8198f31-b406-4177-8dee-f6216c356c75"
# OAuth2 scopes
MAGENTA2_OAUTH_SCOPE = "openid profile offline_access tvhubs"
# OAuth2 redirect URI
MAGENTA2_REDIRECT_URI = "https://web2.magentatv.de/authn/idm"
# ============================================================================
# Request Headers Configuration
# ============================================================================
# Headers for different API endpoints
MAGENTA2_HEADERS = {
"DEFAULT": {"Content-Type": "application/json", "Accept": "application/json"},
"SSO": {
"User-Agent": SSO_USER_AGENT,
"Content-Type": "application/json",
"origin": "https://web2.magentatv.de",
"referer": "https://web2.magentatv.de/",
},
"DCM": {"Content-Type": "application/json", "Accept": "application/json"},
"OAUTH2": {"Content-Type": "application/x-www-form-urlencoded"},
}
# ============================================================================
# Authentication Configuration
# ============================================================================
# Grant types
GRANT_TYPES = {
"LINE_AUTH": "urn:com:telekom:ott-app-services:access-auth",
"AUTH_CODE": "authorization_code",
"PASSWORD": "password",
"REFRESH_TOKEN": "refresh_token",
"REMOTE_LOGIN": "urn:telekom:com:grant-type:remote-login",
"CLIENT_CREDENTIALS": "client_credentials",
}
# ============================================================================
# Content Configuration
# ============================================================================
# Content types
CONTENT_TYPE_LIVE = "LIVE"
CONTENT_TYPE_VOD = "VOD"
# Stream modes
MODE_LIVE = "live"
MODE_VOD = "vod"
# ============================================================================
# DRM Configuration
# ============================================================================
# DRM system
DRM_SYSTEM_WIDEVINE = "widevine"
# DRM request headers
DRM_REQUEST_HEADERS = {"Content-Type": "application/octet-stream"}
# ============================================================================
# Request Configuration
# ============================================================================
# Default timeout for HTTP requests (seconds)
DEFAULT_REQUEST_TIMEOUT = 30
# Default maximum retries for failed requests
DEFAULT_MAX_RETRIES = 3
# Default time window for EPG queries (hours)
DEFAULT_EPG_WINDOW_HOURS = 3
# Cache durations (seconds)
BOOTSTRAP_CACHE_DURATION = 3600 # 1 hour
OPENID_CONFIG_CACHE_DURATION = 86400 # 24 hours
MANIFEST_CACHE_DURATION = 7200 # 2 hours
SMIL_CACHE_DURATION = 3600 # 1 hour
# ============================================================================
# Error Codes
# ============================================================================
# Known error codes from Magenta2 API
ERROR_CODES = {
"DEVICE_LIMIT_EXCEEDED": "deviceLimitExceeded",
"PLAYBACK_RESTRICTED": "ENT_RVOD_Playback_Restricted",
"UNAUTHORIZED": "ENT_Unauthorized",
"INVALID_TOKEN": "INVALID_TOKEN",
"SESSION_EXPIRED": "SESSION_EXPIRED",
}
# ============================================================================
# TAA Configuration
# ============================================================================
# TAA request template
TAA_REQUEST_TEMPLATE = {
"accessTokenSource": IDM,
"appVersion": APPVERSION2,
"channel": {"id": "Tv"},
"natco": "DE",
"type": "telekom",
}
# ============================================================================
# Bootstrap Configuration
# ============================================================================
# Bootstrap parameters
BOOTSTRAP_PARAMS = {"$redirect": "false"}
# REMOVED: Old BOOTSTRAP_KEYS - now handled in config_models.py
# ============================================================================
# Quality Configuration
# ============================================================================
# Ordered quality preference fallback chains used by both live-channel selection
# and VOD playback. Key = desired quality; value = ordered list to try.
QUALITY_FALLBACK: dict = {
"UHDHDR": ["UHDHDR", "UHD", "HD", "SD"],
"UHD": ["UHD", "HD", "SD"],
"HD": ["HD", "SD"],
"SD": ["SD"],
}
# Integer rank per quality label — used for fast channel deduplication when
# multiple entries share the same display number (keep the highest-ranked one).
QUALITY_RANK: dict = {
"SD": 1,
"HD": 2,
"UHD": 3,
"UHDHDR": 4,
"4K": 3, # treat 4K as equivalent to UHD for ranking purposes
}
# ============================================================================
# VOD Configuration
# ============================================================================
# tvhubs base URL template — {client_model} is resolved at runtime from
# CLIENT_MODEL_MAPPINGS. This is a fallback; the live value should come
# from the manifest's tv_hubs.base_urls["ftv"] (or equivalent) via
# ProviderConfig.get_resolved_tvhub_url().
TVHUBS_BASE_URL = "https://tvhubs.t-online.de/v3/{client_model}"
# Flex IDs for the VOD catalogue.
# FLEX_ID_VOD_HOME is only used when personal-bar discovery fails (i.e. no
# homeUrl was obtained from bootstrap/manifest).
# FLEX_ID_VOD_DETAILS is stable across platforms — no discovery equivalent.
VOD_FLEX_ID_HOME = "164035" # StructuredGrid fallback for VOD home screen
VOD_FLEX_ID_DETAILS = "202887" # VodDetails flex ID
VOD_FLEX_ID_PLAYER = "202889" # VodPlayer flex ID
# Pagination default for UnstructuredGrid lane requests
VOD_DEFAULT_PAGE_SIZE = 36
# Content-ID prefixes — used to route get_children() to the correct handler
VOD_PREFIX_SERIES = "GN_SERIES_"
VOD_PREFIX_SEASON = "GN_SEASON_"
VOD_PREFIX_EPISODE = "GN_EP"
VOD_PREFIX_MOVIE_MV = "GN_MV"
VOD_PREFIX_MOVIE_SH = "GN_SH"
# ============================================================================
# PVR / Recordings Configuration
# ============================================================================
# nPVR API endpoint path (appended to pvrBaseUrl from manifest)
PVR_GET_RECORDINGS_PATH = "/get-recordings"
PVR_RECORDINGS_PATH = "/recordings"
# Default and maximum page sizes for the nPVR get-recordings endpoint
PVR_DEFAULT_PAGE_LIMIT = 500
PVR_MAX_PAGE_LIMIT = 500
# Recording statuses used in the byRecordingStatus query parameter.
# The API accepts a pipe-separated list.
#
# Active statuses (exclude soft-deleted recordings) — used by default:
PVR_RECORDING_STATUSES_ACTIVE = [
"SCHEDULED",
"RECORDING",
"RECORDED",
"GENERATED",
"FAILED",
]
# All statuses including soft-deleted — used when include_deleted=True:
PVR_RECORDING_STATUSES_ALL = [
"SCHEDULED",
"RECORDING",
"RECORDED",
"GENERATED",
"FAILED",
"TO_DELETE",
"DELETED",
]
# Accept header required by the nPVR API (differs from standard JSON endpoints)
PVR_ACCEPT_HEADER = "application/json; v=2; charset=utf-8"
# Timer type IDs — used by TimersManager and get_timer_types()
PVR_TIMER_TYPE_EPG_ONE_SHOT = 1
# Recording statuses that represent pending timers (not yet captured).
# Used as the byRecordingStatus filter in TimersManager.get_timers().
# Kept as a list (like the STATUSES_ACTIVE/ALL siblings) for easy pipe-joining.
PVR_RECORDING_STATUSES_TIMERS = ["SCHEDULED"]
# ============================================================================
# Distribution Package Names
# ============================================================================
# Maps distribution IDs (returned by getApplicableDistributionRights) to
# human-readable package names. Used only for logging — the raw IDs are still
# passed to the entitled-channels feed as before.
DISTRIBUTION_PACKAGE_NAMES: dict = {
366135709: "All",
268235282: "Magenta TV Basic",
268235291: "HD & UHD Package",
376449962: "FAST Channels",
347334781: "MagentaSport & UHD Package",
326643267: "Sky Sport + Bundesliga",
424231094: "Sky Sport",
424239773: "Sky Sport Bundesliga",
268235273: "MagentaSport / myTeamTV",
268236341: "Turkish Basic",
268234936: "Turkish Premium",
268235877: "Italian",
268234482: "Polish",
268234476: "RTL Premium",
338937809: "Sky Sport News",
452131099: "Fußball TV UHD",
376449959: "Empty",
}