mirror of
https://github.com/DYefremov/DemonEditor.git
synced 2025-12-30 04:19:41 +01:00
273 lines
8.7 KiB
Python
273 lines
8.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
#
|
|
# The MIT License (MIT)
|
|
#
|
|
# Copyright (c) 2018-2022 Dmitriy Yefremov
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
# in the Software without restriction, including without limitation the rights
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in
|
|
# all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
# THE SOFTWARE.
|
|
#
|
|
# Author: Dmitriy Yefremov
|
|
#
|
|
|
|
|
|
""" Common elements module. """
|
|
from collections import namedtuple
|
|
from enum import Enum
|
|
|
|
from app.commons import log
|
|
|
|
Service = namedtuple("Service", ["flags_cas", "transponder_type", "coded", "service", "locked", "hide", "package",
|
|
"service_type", "picon", "picon_id", "ssid", "freq", "rate", "pol", "fec",
|
|
"system", "pos", "data_id", "fav_id", "transponder"])
|
|
|
|
|
|
# ***************** Bouquets *******************#
|
|
|
|
class BqServiceType(Enum):
|
|
DEFAULT = "DEFAULT"
|
|
IPTV = "IPTV"
|
|
MARKER = "MARKER" # 64
|
|
SPACE = "SPACE" # 832 [hidden marker]
|
|
ALT = "ALT" # Service with alternatives
|
|
BOUQUET = "BOUQUET" # Sub bouquet.
|
|
|
|
@classmethod
|
|
def _missing_(cls, value):
|
|
return cls.DEFAULT
|
|
|
|
|
|
Bouquet = namedtuple("Bouquet", ["name", "type", "services", "locked", "hidden", "file"])
|
|
Bouquet.__new__.__defaults__ = (None, BqServiceType.DEFAULT, [], None, None, None) # For Python3 < 3.7
|
|
Bouquets = namedtuple("Bouquets", ["name", "type", "bouquets"])
|
|
BouquetService = namedtuple("BouquetService", ["name", "type", "data", "num"])
|
|
|
|
# *************** *.xml [Satellites, Terrestrial, Cable] ***************** #
|
|
|
|
Satellite = namedtuple("Satellite", ["name", "flags", "position", "transponders"])
|
|
Terrestrial = namedtuple("Terrestrial", ["name", "flags", "countrycode", "transponders"])
|
|
Cable = namedtuple("Cable", ["name", "flags", "satfeed", "countrycode", "transponders"])
|
|
|
|
Transponder = namedtuple("Transponder", ["frequency", "symbol_rate", "polarization", "fec_inner", "system",
|
|
"modulation", "pls_mode", "pls_code", "is_id", "t2mi_plp_id"])
|
|
TerTransponder = namedtuple("TerTransponder", ["centre_frequency", "system", "bandwidth", "constellation",
|
|
"code_rate_hp", "code_rate_lp", "guard_interval", "transmission_mode",
|
|
"hierarchy_information", "inversion", "plp_id"])
|
|
CableTransponder = namedtuple("CableTransponder", ["frequency", "symbol_rate", "fec_inner", "modulation"])
|
|
|
|
|
|
class TrType(Enum):
|
|
""" Transponders type """
|
|
Satellite = "s"
|
|
Terrestrial = "t"
|
|
Cable = "c"
|
|
ATSC = "a"
|
|
|
|
|
|
class BqType(Enum):
|
|
""" Bouquet type. """
|
|
BOUQUET = "bouquet"
|
|
TV = "tv"
|
|
RADIO = "radio"
|
|
WEBTV = "webtv"
|
|
MARKER = "marker"
|
|
|
|
@classmethod
|
|
def _missing_(cls, value):
|
|
return cls.TV
|
|
|
|
|
|
class Flag(Enum):
|
|
""" Service flags
|
|
|
|
K - last bit (1)
|
|
H - second from end (10)
|
|
P - third (100)
|
|
N - sixth (100000)
|
|
"""
|
|
KEEP = 1 # Do not automatically update the services parameters.
|
|
HIDE = 2
|
|
PIDS = 4 # Always use the cached instead of current pids.
|
|
LOCK = 8
|
|
NEW = 40 # Marked as new at the last scan
|
|
|
|
@staticmethod
|
|
def is_hide(value: int):
|
|
return value & 1 << 1
|
|
|
|
@staticmethod
|
|
def is_keep(value: int):
|
|
return value & 1 << 0
|
|
|
|
@staticmethod
|
|
def is_pids(value: int):
|
|
return value & 1 << 2
|
|
|
|
@staticmethod
|
|
def is_new(value: int):
|
|
return value & 1 << 5
|
|
|
|
@staticmethod
|
|
def parse(value: str) -> int:
|
|
""" Returns an int representation of the flag value.
|
|
|
|
The flag value is usually represented by the number [int],
|
|
but can also be appear in hex format.
|
|
"""
|
|
if len(value) < 3:
|
|
return 0
|
|
|
|
value = value[2:]
|
|
if value.isdigit():
|
|
return int(value)
|
|
return int(value, 16)
|
|
|
|
|
|
class Pids(Enum):
|
|
VIDEO = "c:00"
|
|
AUDIO = "c:01"
|
|
TELETEXT = "c:02"
|
|
PCR = "c:03"
|
|
AC3 = "c:04"
|
|
VIDEO_TYPE = "c:05"
|
|
AUDIO_CHANNEL = "c:06"
|
|
BIT_STREAM_DELAY = "c:07" # in ms
|
|
PCM_DELAY = "c:08" # in ms
|
|
SUBTITLE = "c:09"
|
|
|
|
|
|
class Inversion(Enum):
|
|
Off = "0"
|
|
On = "1"
|
|
Auto = "2"
|
|
|
|
@classmethod
|
|
def _missing_(cls, value):
|
|
return cls.Auto
|
|
|
|
|
|
class Pilot(Enum):
|
|
Off = "0"
|
|
On = "1"
|
|
Auto = "2"
|
|
|
|
@classmethod
|
|
def _missing_(cls, value):
|
|
return cls.Auto
|
|
|
|
|
|
class SystemCable(Enum):
|
|
""" System of cable service """
|
|
ANNEX_A = "0"
|
|
ANNEX_C = "1"
|
|
|
|
|
|
ROLL_OFF = {"0": "35%", "1": "25%", "2": "20%", "3": "Auto"}
|
|
|
|
POLARIZATION = {"0": "H", "1": "V", "2": "L", "3": "R"}
|
|
|
|
PLS_MODE = {"0": "Root", "1": "Gold", "2": "Combo"}
|
|
|
|
FEC = {"0": "Auto", "1": "1/2", "2": "2/3", "3": "3/4", "4": "5/6", "5": "7/8", "6": "8/9", "7": "3/5", "8": "4/5",
|
|
"9": "9/10", "10": "1/2", "11": "2/3", "12": "3/4", "13": "5/6", "14": "7/8", "15": "8/9", "16": "3/5",
|
|
"17": "4/5", "18": "9/10", "19": "1/2", "20": "2/3", "21": "3/4", "22": "5/6", "23": "7/8", "24": "8/9",
|
|
"25": "3/5", "26": "4/5", "27": "9/10", "28": "Auto"}
|
|
|
|
FEC_DEFAULT = {"0": "Auto", "1": "1/2", "2": "2/3", "3": "3/4", "4": "5/6", "5": "7/8", "6": "8/9", "7": "3/5",
|
|
"8": "4/5", "9": "9/10", "10": "6/7", "15": "None"}
|
|
|
|
SYSTEM = {"0": "DVB-S", "1": "DVB-S2"}
|
|
|
|
MODULATION = {"0": "Auto", "1": "QPSK", "2": "8PSK", "4": "16APSK", "5": "32APSK"}
|
|
|
|
SERVICE_TYPE = {"-2": "Data", "1": "TV", "2": "Radio", "3": "Data", "10": "Radio", "22": "TV (H264)",
|
|
"25": "TV (HD)", "31": "TV (UHD)"}
|
|
|
|
# Terrestrial
|
|
BANDWIDTH = {"0": "8MHz", "1": "7MHz", "2": "6MHz", "3": "Auto", "4": "5MHz", "5": "1/712MHz", "6": "10MHz"}
|
|
|
|
CONSTELLATION = {"0": "QPSK", "1": "16-QAM", "2": "64-QAM", "3": "Auto"}
|
|
|
|
T_MODULATION = {"0": "QPSK", "1": "QAM16", "2": "QAM64", "3": "Auto", "4": "QAM256"}
|
|
|
|
TRANSMISSION_MODE = {"0": "2k", "1": "8k", "2": "Auto", "3": "4k", "4": "1k", "5": "16k", "6": "32k"}
|
|
|
|
GUARD_INTERVAL = {"0": "1/32", "1": "1/16", "2": "1/8", "3": "1/4", "4": "Auto", "5": "1/128", "6": "19/128",
|
|
"7": "19/256"}
|
|
|
|
HIERARCHY = {"0": "None", "1": "1", "2": "2", "3": "4", "4": "Auto"}
|
|
|
|
T_FEC = {"0": "1/2", "1": "2/3", "2": "3/4", "3": "5/6", "4": "7/8", "5": "Auto", "6": "6/7", "7": "8/9"}
|
|
|
|
T_SYSTEM = {"0": "DVB-T", "1": "DVB-T2", "-1": "DVB-T/T2"}
|
|
|
|
# Cable
|
|
C_MODULATION = {"0": "QPSK", "1": "QAM16", "2": "QAM32", "3": "QAM64", "4": "QAM128", "5": "QAM256", "6": "Auto"}
|
|
|
|
# ATSC
|
|
A_MODULATION = {"0": "Auto", "1": "QAM16", "2": "QAM32", "3": "QAM64", "4": "QAM128", "5": "QAM256", "6": "8VSB",
|
|
"7": "16VSB"}
|
|
|
|
# CAS
|
|
CAS = {"C:26": "BISS", "C:0B": "Conax", "C:06": "Irdeto", "C:18": "Nagravision", "C:05": "Viaccess", "C:01": "SECA",
|
|
"C:0E": "PowerVu", "C:4A": "DRE-Crypt", "C:7B": "DRE-Crypt", "C:56": "Verimatrix", "C:09": "VideoGuard"}
|
|
|
|
# 'on' attribute 0070(hex) = 112(int) = ONID(ONID-TID on www.lyngsat.com)
|
|
PROVIDER = {112: "HTB+", 253: "Tricolor TV"}
|
|
|
|
|
|
# ************* subsidiary functions ****************
|
|
|
|
def get_key_by_value(dc: dict, value):
|
|
""" Returns key from dict by value """
|
|
for k, v in dc.items():
|
|
if v == value:
|
|
return k
|
|
|
|
|
|
def get_value_by_name(en, name):
|
|
""" Returns value by name from enums """
|
|
for n in en:
|
|
if n.name == name:
|
|
return n.value
|
|
|
|
|
|
def is_transponder_valid(tr: Transponder):
|
|
""" Checks transponder validity. """
|
|
try:
|
|
int(tr.frequency)
|
|
int(tr.symbol_rate)
|
|
tr.pls_mode is None or int(tr.pls_mode)
|
|
tr.pls_code is None or int(tr.pls_code)
|
|
tr.is_id is None or int(tr.is_id)
|
|
tr.t2mi_plp_id is None or int(tr.t2mi_plp_id)
|
|
except (TypeError, ValueError) as e:
|
|
log(f"Transponder validation error: {e}\n{tr}")
|
|
return False
|
|
|
|
if tr.polarization not in POLARIZATION:
|
|
return False
|
|
if tr.fec_inner not in FEC:
|
|
return False
|
|
if tr.system not in SYSTEM:
|
|
return False
|
|
if tr.modulation not in MODULATION:
|
|
return False
|
|
|
|
return True
|