mirror of
https://github.com/DYefremov/DemonEditor.git
synced 2026-03-04 19:41:41 +01:00
settings refactoring
This commit is contained in:
@@ -12,7 +12,7 @@ from urllib.parse import urlencode
|
||||
from urllib.request import urlopen, HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener, install_opener
|
||||
|
||||
from app.commons import log
|
||||
from app.settings import Profile
|
||||
from app.settings import SettingsType
|
||||
|
||||
_BQ_FILES_LIST = ("tv", "radio", # enigma 2
|
||||
"myservices.xml", "bouquets.xml", "ubouquets.xml") # neutrino
|
||||
@@ -49,7 +49,7 @@ def download_data(*, settings, download_type=DownloadType.ALL, callback=print):
|
||||
with FTP(host=settings.host, user=settings.user, passwd=settings.password) as ftp:
|
||||
ftp.encoding = "utf-8"
|
||||
callback("FTP OK.\n")
|
||||
save_path = settings.data_dir_path
|
||||
save_path = settings.data_local_path
|
||||
os.makedirs(os.path.dirname(save_path), exist_ok=True)
|
||||
files = []
|
||||
# bouquets
|
||||
@@ -94,14 +94,14 @@ def download_data(*, settings, download_type=DownloadType.ALL, callback=print):
|
||||
|
||||
def upload_data(*, settings, download_type=DownloadType.ALL, remove_unused=False,
|
||||
callback=print, done_callback=None, use_http=False):
|
||||
profile = settings.profile
|
||||
data_path = settings.data_dir_path
|
||||
s_type = settings.setting_type
|
||||
data_path = settings.data_local_path
|
||||
host = settings.host
|
||||
base_url = "http://{}:{}/api/".format(host, settings.http_port)
|
||||
tn, ht = None, None # telnet, http
|
||||
|
||||
try:
|
||||
if profile is Profile.ENIGMA_2 and use_http:
|
||||
if s_type is SettingsType.ENIGMA_2 and use_http:
|
||||
ht = http(settings.http_user, settings.http_password, base_url, callback)
|
||||
next(ht)
|
||||
message = ""
|
||||
@@ -139,7 +139,7 @@ def upload_data(*, settings, download_type=DownloadType.ALL, remove_unused=False
|
||||
if download_type is DownloadType.SATELLITES:
|
||||
upload_xml(ftp, data_path, sat_xml_path, _SAT_XML_FILE, callback)
|
||||
|
||||
if profile is Profile.NEUTRINO_MP and download_type is DownloadType.WEBTV:
|
||||
if s_type is SettingsType.NEUTRINO_MP and download_type is DownloadType.WEBTV:
|
||||
upload_xml(ftp, data_path, sat_xml_path, _WEBTV_XML_FILE, callback)
|
||||
|
||||
if download_type is DownloadType.BOUQUETS:
|
||||
@@ -148,7 +148,7 @@ def upload_data(*, settings, download_type=DownloadType.ALL, remove_unused=False
|
||||
|
||||
if download_type is DownloadType.ALL:
|
||||
upload_xml(ftp, data_path, sat_xml_path, _SAT_XML_FILE, callback)
|
||||
if profile is Profile.NEUTRINO_MP:
|
||||
if s_type is SettingsType.NEUTRINO_MP:
|
||||
upload_xml(ftp, data_path, sat_xml_path, _WEBTV_XML_FILE, callback)
|
||||
|
||||
ftp.cwd(services_path)
|
||||
@@ -156,11 +156,11 @@ def upload_data(*, settings, download_type=DownloadType.ALL, remove_unused=False
|
||||
upload_files(ftp, data_path, _DATA_FILES_LIST, callback)
|
||||
|
||||
if download_type is DownloadType.PICONS:
|
||||
upload_picons(ftp, settings.picons_dir_path, settings.picons_path, callback)
|
||||
upload_picons(ftp, settings.picons_local_path, settings.picons_path, callback)
|
||||
|
||||
if tn and not use_http:
|
||||
# resume enigma or restart neutrino
|
||||
tn.send("init 3" if profile is Profile.ENIGMA_2 else "init 6")
|
||||
tn.send("init 3" if s_type is SettingsType.ENIGMA_2 else "init 6")
|
||||
elif ht and use_http:
|
||||
if download_type is DownloadType.BOUQUETS:
|
||||
ht.send(base_url + "/servicelistreload?mode=2")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from app.commons import run_task
|
||||
from app.settings import Profile
|
||||
from app.settings import SettingsType
|
||||
from .ecommons import Service, Satellite, Transponder, Bouquet, Bouquets, is_transponder_valid
|
||||
from .enigma.blacklist import get_blacklist, write_blacklist
|
||||
from .enigma.bouquets import get_bouquets as get_enigma_bouquets, write_bouquets as write_enigma_bouquets, to_bouquet_id
|
||||
@@ -10,33 +10,33 @@ from .neutrino.services import get_services as get_neutrino_services, write_serv
|
||||
from .satxml import get_satellites, write_satellites
|
||||
|
||||
|
||||
def get_services(data_path, profile, format_version):
|
||||
if profile is Profile.ENIGMA_2:
|
||||
def get_services(data_path, s_type, format_version):
|
||||
if s_type is SettingsType.ENIGMA_2:
|
||||
return get_enigma_services(data_path, format_version)
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
elif s_type is SettingsType.NEUTRINO_MP:
|
||||
return get_neutrino_services(data_path)
|
||||
|
||||
|
||||
@run_task
|
||||
def write_services(path, channels, profile, format_version):
|
||||
if profile is Profile.ENIGMA_2:
|
||||
def write_services(path, channels, s_type, format_version):
|
||||
if s_type is SettingsType.ENIGMA_2:
|
||||
write_enigma_services(path, channels, format_version)
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
elif s_type is SettingsType.NEUTRINO_MP:
|
||||
write_neutrino_services(path, channels)
|
||||
|
||||
|
||||
def get_bouquets(path, profile):
|
||||
if profile is Profile.ENIGMA_2:
|
||||
def get_bouquets(path, s_type):
|
||||
if s_type is SettingsType.ENIGMA_2:
|
||||
return get_enigma_bouquets(path)
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
elif s_type is SettingsType.NEUTRINO_MP:
|
||||
return get_neutrino_bouquets(path)
|
||||
|
||||
|
||||
@run_task
|
||||
def write_bouquets(path, bouquets, profile):
|
||||
if profile is Profile.ENIGMA_2:
|
||||
def write_bouquets(path, bouquets, s_type):
|
||||
if s_type is SettingsType.ENIGMA_2:
|
||||
write_enigma_bouquets(path, bouquets)
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
elif s_type is SettingsType.NEUTRINO_MP:
|
||||
write_neutrino_bouquets(path, bouquets)
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import re
|
||||
import urllib.request
|
||||
from enum import Enum
|
||||
|
||||
from app.settings import Profile
|
||||
from app.settings import SettingsType
|
||||
from app.ui.uicommons import IPTV_ICON
|
||||
from .ecommons import BqServiceType, Service
|
||||
|
||||
@@ -20,18 +20,18 @@ class StreamType(Enum):
|
||||
NONE_REC_2 = "5002"
|
||||
|
||||
|
||||
def parse_m3u(path, profile):
|
||||
def parse_m3u(path, s_type):
|
||||
with open(path) as file:
|
||||
aggr = [None] * 10
|
||||
services = []
|
||||
groups = set()
|
||||
counter = 0
|
||||
name = None
|
||||
|
||||
|
||||
for line in file.readlines():
|
||||
if line.startswith("#EXTINF"):
|
||||
name = line[1 + line.index(","):].strip()
|
||||
elif line.startswith("#EXTGRP") and profile is Profile.ENIGMA_2:
|
||||
elif line.startswith("#EXTGRP") and s_type is SettingsType.ENIGMA_2:
|
||||
grp_name = line.strip("#EXTGRP:").strip()
|
||||
if grp_name not in groups:
|
||||
groups.add(grp_name)
|
||||
@@ -41,7 +41,7 @@ def parse_m3u(path, profile):
|
||||
services.append(mr)
|
||||
elif not line.startswith("#"):
|
||||
url = line.strip()
|
||||
fav_id = get_fav_id(url, name, profile)
|
||||
fav_id = get_fav_id(url, name, s_type)
|
||||
if name and url:
|
||||
srv = Service(None, None, IPTV_ICON, name, *aggr[0:3], BqServiceType.IPTV.name, *aggr, fav_id, None)
|
||||
services.append(srv)
|
||||
@@ -49,8 +49,8 @@ def parse_m3u(path, profile):
|
||||
return services
|
||||
|
||||
|
||||
def export_to_m3u(path, bouquet, profile):
|
||||
pattern = re.compile(".*:(http.*):.*") if profile is Profile.ENIGMA_2 else re.compile("(http.*?)::::.*")
|
||||
def export_to_m3u(path, bouquet, s_type):
|
||||
pattern = re.compile(".*:(http.*):.*") if s_type is SettingsType.ENIGMA_2 else re.compile("(http.*?)::::.*")
|
||||
lines = ["#EXTM3U\n"]
|
||||
current_grp = None
|
||||
|
||||
@@ -72,13 +72,13 @@ def export_to_m3u(path, bouquet, profile):
|
||||
file.writelines(lines)
|
||||
|
||||
|
||||
def get_fav_id(url, service_name, profile):
|
||||
def get_fav_id(url, service_name, s_type):
|
||||
""" Returns fav id depending on the profile. """
|
||||
if profile is Profile.ENIGMA_2:
|
||||
if s_type is SettingsType.ENIGMA_2:
|
||||
url = urllib.request.quote(url)
|
||||
stream_type = StreamType.NONE_TS.value
|
||||
return ENIGMA2_FAV_ID_FORMAT.format(stream_type, 1, 0, 0, 0, 0, url, service_name, service_name, None)
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
elif s_type is SettingsType.NEUTRINO_MP:
|
||||
return NEUTRINO_FAV_ID_FORMAT.format(url, "", 0, None, None, None, None, "", "", 1)
|
||||
|
||||
|
||||
|
||||
305
app/settings.py
305
app/settings.py
@@ -2,7 +2,7 @@ import json
|
||||
import os
|
||||
from pprint import pformat
|
||||
from textwrap import dedent
|
||||
from enum import Enum
|
||||
from enum import Enum, IntEnum
|
||||
from pathlib import Path
|
||||
|
||||
CONFIG_PATH = str(Path.home()) + "/.config/demon-editor/"
|
||||
@@ -10,19 +10,85 @@ CONFIG_FILE = CONFIG_PATH + "config.json"
|
||||
DATA_PATH = "data/"
|
||||
|
||||
|
||||
class Profile(Enum):
|
||||
class Defaults(Enum):
|
||||
""" Default program settings """
|
||||
DEFAULT_PROFILE = "default"
|
||||
BACKUP_BEFORE_DOWNLOADING = True
|
||||
BACKUP_BEFORE_SAVE = True
|
||||
V5_SUPPORT = False
|
||||
HTTP_API_SUPPORT = False
|
||||
ENABLE_YT_DL = False
|
||||
ENABLE_SEND_TO = False
|
||||
USE_COLORS = True
|
||||
NEW_COLOR = "rgb(255,230,204)"
|
||||
EXTRA_COLOR = "rgb(179,230,204)"
|
||||
FAV_CLICK_MODE = 0
|
||||
|
||||
|
||||
def get_default_settings():
|
||||
return {
|
||||
"version": 1,
|
||||
"default_profile": Defaults.DEFAULT_PROFILE.value,
|
||||
"profiles": {"default": SettingsType.ENIGMA_2.get_default_settings()},
|
||||
"v5_support": Defaults.V5_SUPPORT.value,
|
||||
"http_api_support": Defaults.HTTP_API_SUPPORT.value,
|
||||
"enable_yt_dl": Defaults.ENABLE_YT_DL.value,
|
||||
"enable_send_to": Defaults.ENABLE_SEND_TO.value,
|
||||
"use_colors": Defaults.USE_COLORS.value,
|
||||
"new_color": Defaults.NEW_COLOR.value,
|
||||
"extra_color": Defaults.EXTRA_COLOR.value,
|
||||
"fav_click_mode": Defaults.FAV_CLICK_MODE.value
|
||||
}
|
||||
|
||||
|
||||
class SettingsType(IntEnum):
|
||||
""" Profiles for settings """
|
||||
ENIGMA_2 = "0"
|
||||
NEUTRINO_MP = "1"
|
||||
ENIGMA_2 = 0
|
||||
NEUTRINO_MP = 1
|
||||
|
||||
def get_default_settings(self):
|
||||
""" Returns default settings for current type """
|
||||
if self is self.ENIGMA_2:
|
||||
return {"setting_type": self,
|
||||
"host": "127.0.0.1", "port": "21", "user": "root", "password": "root", "timeout": 5,
|
||||
"http_user": "root", "http_password": "", "http_port": "80", "http_timeout": 5,
|
||||
"telnet_user": "root", "telnet_password": "", "telnet_port": "23", "telnet_timeout": 5,
|
||||
"services_path": "/etc/enigma2/", "user_bouquet_path": "/etc/enigma2/",
|
||||
"satellites_xml_path": "/etc/tuxbox/", "data_local_path": DATA_PATH + "enigma2/",
|
||||
"picons_path": "/usr/share/enigma2/picon",
|
||||
"picons_local_path": DATA_PATH + "enigma2/picons/",
|
||||
"backup_local_path": DATA_PATH + "enigma2/backup/"}
|
||||
elif self is self.NEUTRINO_MP:
|
||||
return {"setting_type": self,
|
||||
"host": "127.0.0.1", "port": "21", "user": "root", "password": "root", "timeout": 5,
|
||||
"http_user": "", "http_password": "", "http_port": "80", "http_timeout": 2,
|
||||
"telnet_user": "root", "telnet_password": "", "telnet_port": "23", "telnet_timeout": 1,
|
||||
"services_path": "/var/tuxbox/config/zapit/", "user_bouquet_path": "/var/tuxbox/config/zapit/",
|
||||
"satellites_xml_path": "/var/tuxbox/config/", "data_local_path": DATA_PATH + "neutrino/",
|
||||
"picons_path": "/usr/share/tuxbox/neutrino/icons/logo/",
|
||||
"picons_local_path": DATA_PATH + "neutrino/picons/",
|
||||
"backup_local_path": DATA_PATH + "neutrino/backup/"}
|
||||
|
||||
|
||||
class SettingsException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Settings:
|
||||
__INSTANCE = None
|
||||
__VERSION = 1
|
||||
|
||||
def __init__(self):
|
||||
self._config = get_config()
|
||||
self._current_profile = Profile(self._config.get("profile"))
|
||||
self._current_profile_options = self._config.get(self._current_profile.value)
|
||||
settings = get_settings()
|
||||
|
||||
if self.__VERSION > settings.get("version", 0):
|
||||
write_settings(get_default_settings())
|
||||
raise SettingsException("Outdated version of the settings format!")
|
||||
|
||||
self._settings = settings
|
||||
self._current_profile = self._settings.get("default_profile", "default")
|
||||
self._profiles = self._settings.get("profiles", {"default": SettingsType.ENIGMA_2.get_default_settings()})
|
||||
self._cp_settings = self._profiles.get(self._current_profile) # Current profile settings
|
||||
|
||||
def __str__(self):
|
||||
return dedent(""" Current profile: {}
|
||||
@@ -31,8 +97,8 @@ class Settings:
|
||||
Full config:
|
||||
{}
|
||||
""").format(self._current_profile,
|
||||
pformat(self._current_profile_options),
|
||||
pformat(self._config))
|
||||
pformat(self._cp_settings),
|
||||
pformat(self._settings))
|
||||
|
||||
@classmethod
|
||||
def get_instance(cls):
|
||||
@@ -41,325 +107,296 @@ class Settings:
|
||||
return cls.__INSTANCE
|
||||
|
||||
def save(self):
|
||||
write_config(self._config)
|
||||
write_settings(self._settings)
|
||||
|
||||
def reset(self, force_write=False):
|
||||
def_settings = get_default_settings()
|
||||
for p in Profile:
|
||||
current = self._config.get(p.value)
|
||||
default = def_settings.get(p.value)
|
||||
for k in default:
|
||||
current[k] = default.get(k)
|
||||
for k, v in self.setting_type.get_default_settings().items():
|
||||
self._cp_settings[k] = v
|
||||
|
||||
if force_write:
|
||||
write_config(get_default_settings())
|
||||
self.save()
|
||||
|
||||
def get_default(self, p_name):
|
||||
""" Returns default value for current settings type """
|
||||
return self.setting_type.get_default_settings().get(p_name)
|
||||
|
||||
def add(self, name, value):
|
||||
""" Adds extra options """
|
||||
self._config[name] = value
|
||||
self._settings[name] = value
|
||||
|
||||
def get(self, name):
|
||||
""" Returns extra options """
|
||||
return self._config.get(name, None)
|
||||
|
||||
def get_default(self, name):
|
||||
""" Returns default value of the option """
|
||||
return get_default_settings().get(self._current_profile.value).get(name)
|
||||
""" Returns extra options or None """
|
||||
return self._settings.get(name, None)
|
||||
|
||||
@property
|
||||
def presets(self):
|
||||
raise NotImplementedError
|
||||
def profiles(self):
|
||||
return self._profiles
|
||||
|
||||
@presets.setter
|
||||
def presets(self, name):
|
||||
raise NotImplementedError
|
||||
@profiles.setter
|
||||
def profiles(self, ps):
|
||||
self._profiles = ps
|
||||
self._settings["profiles"] = self._profiles
|
||||
|
||||
@property
|
||||
def profile(self):
|
||||
return self._current_profile
|
||||
def setting_type(self):
|
||||
return SettingsType(self._cp_settings.get("setting_type", SettingsType.ENIGMA_2.value))
|
||||
|
||||
@profile.setter
|
||||
def profile(self, prf):
|
||||
self._current_profile = prf
|
||||
self._config["profile"] = prf.value
|
||||
self._current_profile_options = self._config.get(prf.value)
|
||||
@setting_type.setter
|
||||
def setting_type(self, s_type):
|
||||
self._cp_settings["setting_type"] = s_type
|
||||
for k, v in s_type.get_default_settings().items():
|
||||
self._cp_settings[k] = v
|
||||
|
||||
@property
|
||||
def host(self):
|
||||
return self._current_profile_options.get("host", self.get_default("host"))
|
||||
return self._cp_settings.get("host", self.get_default("host"))
|
||||
|
||||
@host.setter
|
||||
def host(self, value):
|
||||
self._current_profile_options["host"] = value
|
||||
self._cp_settings["host"] = value
|
||||
|
||||
@property
|
||||
def port(self):
|
||||
return self._current_profile_options.get("port", self.get_default("port"))
|
||||
return self._cp_settings.get("port", self.get_default("port"))
|
||||
|
||||
@port.setter
|
||||
def port(self, value):
|
||||
self._current_profile_options["port"] = value
|
||||
self._cp_settings["port"] = value
|
||||
|
||||
@property
|
||||
def user(self):
|
||||
return self._current_profile_options.get("user", self.get_default("user"))
|
||||
return self._cp_settings.get("user", self.get_default("user"))
|
||||
|
||||
@user.setter
|
||||
def user(self, value):
|
||||
self._current_profile_options["user"] = value
|
||||
self._cp_settings["user"] = value
|
||||
|
||||
@property
|
||||
def password(self):
|
||||
return self._current_profile_options.get("password", self.get_default("password"))
|
||||
return self._cp_settings.get("password", self.get_default("password"))
|
||||
|
||||
@password.setter
|
||||
def password(self, value):
|
||||
self._current_profile_options["password"] = value
|
||||
self._cp_settings["password"] = value
|
||||
|
||||
@property
|
||||
def http_user(self):
|
||||
return self._current_profile_options.get("http_user", self.get_default("http_user"))
|
||||
return self._cp_settings.get("http_user", self.get_default("http_user"))
|
||||
|
||||
@http_user.setter
|
||||
def http_user(self, value):
|
||||
self._current_profile_options["http_user"] = value
|
||||
self._cp_settings["http_user"] = value
|
||||
|
||||
@property
|
||||
def http_password(self):
|
||||
return self._current_profile_options.get("http_password", self.get_default("http_password"))
|
||||
return self._cp_settings.get("http_password", self.get_default("http_password"))
|
||||
|
||||
@http_password.setter
|
||||
def http_password(self, value):
|
||||
self._current_profile_options["http_password"] = value
|
||||
self._cp_settings["http_password"] = value
|
||||
|
||||
@property
|
||||
def http_port(self):
|
||||
return self._current_profile_options.get("http_port", self.get_default("http_port"))
|
||||
return self._cp_settings.get("http_port", self.get_default("http_port"))
|
||||
|
||||
@http_port.setter
|
||||
def http_port(self, value):
|
||||
self._current_profile_options["http_port"] = value
|
||||
self._cp_settings["http_port"] = value
|
||||
|
||||
@property
|
||||
def http_timeout(self):
|
||||
return self._current_profile_options.get("http_timeout", self.get_default("http_timeout"))
|
||||
return self._cp_settings.get("http_timeout", self.get_default("http_timeout"))
|
||||
|
||||
@http_timeout.setter
|
||||
def http_timeout(self, value):
|
||||
self._current_profile_options["http_timeout"] = value
|
||||
self._cp_settings["http_timeout"] = value
|
||||
|
||||
@property
|
||||
def telnet_user(self):
|
||||
return self._current_profile_options.get("telnet_user", self.get_default("telnet_user"))
|
||||
return self._cp_settings.get("telnet_user", self.get_default("telnet_user"))
|
||||
|
||||
@telnet_user.setter
|
||||
def telnet_user(self, value):
|
||||
self._current_profile_options["telnet_user"] = value
|
||||
self._cp_settings["telnet_user"] = value
|
||||
|
||||
@property
|
||||
def telnet_password(self):
|
||||
return self._current_profile_options.get("telnet_password", self.get_default("telnet_password"))
|
||||
return self._cp_settings.get("telnet_password", self.get_default("telnet_password"))
|
||||
|
||||
@telnet_password.setter
|
||||
def telnet_password(self, value):
|
||||
self._current_profile_options["telnet_password"] = value
|
||||
self._cp_settings["telnet_password"] = value
|
||||
|
||||
@property
|
||||
def telnet_port(self):
|
||||
return self._current_profile_options.get("telnet_port", self.get_default("telnet_port"))
|
||||
return self._cp_settings.get("telnet_port", self.get_default("telnet_port"))
|
||||
|
||||
@telnet_port.setter
|
||||
def telnet_port(self, value):
|
||||
self._current_profile_options["telnet_port"] = value
|
||||
self._cp_settings["telnet_port"] = value
|
||||
|
||||
@property
|
||||
def telnet_timeout(self):
|
||||
return self._current_profile_options.get("telnet_timeout", self.get_default("telnet_timeout"))
|
||||
return self._cp_settings.get("telnet_timeout", self.get_default("telnet_timeout"))
|
||||
|
||||
@telnet_timeout.setter
|
||||
def telnet_timeout(self, value):
|
||||
self._current_profile_options["telnet_timeout"] = value
|
||||
self._cp_settings["telnet_timeout"] = value
|
||||
|
||||
@property
|
||||
def services_path(self):
|
||||
return self._current_profile_options.get("services_path", self.get_default("services_path"))
|
||||
return self._cp_settings.get("services_path", self.get_default("services_path"))
|
||||
|
||||
@services_path.setter
|
||||
def services_path(self, value):
|
||||
self._current_profile_options["services_path"] = value
|
||||
self._cp_settings["services_path"] = value
|
||||
|
||||
@property
|
||||
def user_bouquet_path(self):
|
||||
return self._current_profile_options.get("user_bouquet_path", self.get_default("user_bouquet_path"))
|
||||
return self._cp_settings.get("user_bouquet_path", self.get_default("user_bouquet_path"))
|
||||
|
||||
@user_bouquet_path.setter
|
||||
def user_bouquet_path(self, value):
|
||||
self._current_profile_options["user_bouquet_path"] = value
|
||||
self._cp_settings["user_bouquet_path"] = value
|
||||
|
||||
@property
|
||||
def satellites_xml_path(self):
|
||||
return self._current_profile_options.get("satellites_xml_path", self.get_default("satellites_xml_path"))
|
||||
return self._cp_settings.get("satellites_xml_path", self.get_default("satellites_xml_path"))
|
||||
|
||||
@satellites_xml_path.setter
|
||||
def satellites_xml_path(self, value):
|
||||
self._current_profile_options["satellites_xml_path"] = value
|
||||
self._cp_settings["satellites_xml_path"] = value
|
||||
|
||||
@property
|
||||
def data_dir_path(self):
|
||||
return self._current_profile_options.get("data_dir_path", self.get_default("data_dir_path"))
|
||||
def data_local_path(self):
|
||||
return self._cp_settings.get("data_local_path", self.get_default("data_local_path"))
|
||||
|
||||
@data_dir_path.setter
|
||||
def data_dir_path(self, value):
|
||||
self._current_profile_options["data_dir_path"] = value
|
||||
@data_local_path.setter
|
||||
def data_local_path(self, value):
|
||||
self._cp_settings["data_local_path"] = value
|
||||
|
||||
@property
|
||||
def picons_path(self):
|
||||
return self._current_profile_options.get("picons_path", self.get_default("picons_path"))
|
||||
return self._cp_settings.get("picons_path", self.get_default("picons_path"))
|
||||
|
||||
@picons_path.setter
|
||||
def picons_path(self, value):
|
||||
self._current_profile_options["picons_path"] = value
|
||||
self._cp_settings["picons_path"] = value
|
||||
|
||||
@property
|
||||
def picons_dir_path(self):
|
||||
return self._current_profile_options.get("picons_dir_path", self.get_default("picons_dir_path"))
|
||||
def picons_local_path(self):
|
||||
return self._cp_settings.get("picons_local_path", self.get_default("picons_local_path"))
|
||||
|
||||
@picons_dir_path.setter
|
||||
def picons_dir_path(self, value):
|
||||
self._current_profile_options["picons_dir_path"] = value
|
||||
@picons_local_path.setter
|
||||
def picons_local_path(self, value):
|
||||
self._cp_settings["picons_local_path"] = value
|
||||
|
||||
@property
|
||||
def backup_dir_path(self):
|
||||
return self._current_profile_options.get("backup_dir_path", self.get_default("backup_dir_path"))
|
||||
def backup_local_path(self):
|
||||
return self._cp_settings.get("backup_local_path", self.get_default("backup_local_path"))
|
||||
|
||||
@backup_dir_path.setter
|
||||
def backup_dir_path(self, value):
|
||||
self._current_profile_options["backup_dir_path"] = value
|
||||
@backup_local_path.setter
|
||||
def backup_local_path(self, value):
|
||||
self._cp_settings["backup_local_path"] = value
|
||||
|
||||
# ***** Program settings *****
|
||||
|
||||
@property
|
||||
def backup_before_save(self):
|
||||
return self._current_profile_options.get("backup_before_save", self.get_default("backup_before_save"))
|
||||
return self._settings.get("backup_before_save", Defaults.BACKUP_BEFORE_SAVE.value)
|
||||
|
||||
@backup_before_save.setter
|
||||
def backup_before_save(self, value):
|
||||
self._current_profile_options["backup_before_save"] = value
|
||||
self._settings["backup_before_save"] = value
|
||||
|
||||
@property
|
||||
def backup_before_downloading(self):
|
||||
return self._current_profile_options.get("backup_before_downloading",
|
||||
self.get_default("backup_before_downloading"))
|
||||
return self._settings.get("backup_before_downloading", Defaults.BACKUP_BEFORE_DOWNLOADING.value)
|
||||
|
||||
@backup_before_downloading.setter
|
||||
def backup_before_downloading(self, value):
|
||||
self._current_profile_options["backup_before_downloading"] = value
|
||||
self._settings["backup_before_downloading"] = value
|
||||
|
||||
@property
|
||||
def v5_support(self):
|
||||
return self._current_profile_options.get("v5_support", self.get_default("v5_support"))
|
||||
return self._settings.get("v5_support", Defaults.V5_SUPPORT.value)
|
||||
|
||||
@v5_support.setter
|
||||
def v5_support(self, value):
|
||||
self._current_profile_options["v5_support"] = value
|
||||
self._settings["v5_support"] = value
|
||||
|
||||
@property
|
||||
def http_api_support(self):
|
||||
return self._current_profile_options.get("http_api_support", self.get_default("http_api_support"))
|
||||
return self._settings.get("http_api_support", Defaults.HTTP_API_SUPPORT.value)
|
||||
|
||||
@http_api_support.setter
|
||||
def http_api_support(self, value):
|
||||
self._current_profile_options["http_api_support"] = value
|
||||
self._settings["http_api_support"] = value
|
||||
|
||||
@property
|
||||
def enable_yt_dl(self):
|
||||
return self._current_profile_options.get("enable_yt_dl", self.get_default("enable_yt_dl"))
|
||||
return self._settings.get("enable_yt_dl", Defaults.ENABLE_YT_DL.value)
|
||||
|
||||
@enable_yt_dl.setter
|
||||
def enable_yt_dl(self, value):
|
||||
self._current_profile_options["enable_yt_dl"] = value
|
||||
self._settings["enable_yt_dl"] = value
|
||||
|
||||
@property
|
||||
def enable_send_to(self):
|
||||
return self._current_profile_options.get("enable_send_to", self.get_default("enable_send_to"))
|
||||
return self._settings.get("enable_send_to", Defaults.ENABLE_SEND_TO.value)
|
||||
|
||||
@enable_send_to.setter
|
||||
def enable_send_to(self, value):
|
||||
self._current_profile_options["enable_send_to"] = value
|
||||
self._settings["enable_send_to"] = value
|
||||
|
||||
@property
|
||||
def use_colors(self):
|
||||
return self._current_profile_options.get("use_colors", self.get_default("use_colors"))
|
||||
return self._settings.get("use_colors", Defaults.USE_COLORS.value)
|
||||
|
||||
@use_colors.setter
|
||||
def use_colors(self, value):
|
||||
self._current_profile_options["use_colors"] = value
|
||||
self._settings["use_colors"] = value
|
||||
|
||||
@property
|
||||
def new_color(self):
|
||||
return self._current_profile_options.get("new_color", self.get_default("new_color"))
|
||||
return self._settings.get("new_color", Defaults.NEW_COLOR.value)
|
||||
|
||||
@new_color.setter
|
||||
def new_color(self, value):
|
||||
self._current_profile_options["new_color"] = value
|
||||
self._settings["new_color"] = value
|
||||
|
||||
@property
|
||||
def extra_color(self):
|
||||
return self._current_profile_options.get("extra_color", self.get_default("extra_color"))
|
||||
return self._settings.get("extra_color", Defaults.EXTRA_COLOR.value)
|
||||
|
||||
@extra_color.setter
|
||||
def extra_color(self, value):
|
||||
self._current_profile_options["extra_color"] = value
|
||||
self._settings["extra_color"] = value
|
||||
|
||||
@property
|
||||
def fav_click_mode(self):
|
||||
return self._current_profile_options.get("fav_click_mode", self.get_default("fav_click_mode"))
|
||||
return self._settings.get("fav_click_mode", Defaults.FAV_CLICK_MODE.value)
|
||||
|
||||
@fav_click_mode.setter
|
||||
def fav_click_mode(self, value):
|
||||
self._current_profile_options["fav_click_mode"] = value
|
||||
self._settings["fav_click_mode"] = value
|
||||
|
||||
|
||||
def get_config():
|
||||
def get_settings():
|
||||
os.makedirs(os.path.dirname(CONFIG_PATH), exist_ok=True) # create dir if not exist
|
||||
os.makedirs(os.path.dirname(DATA_PATH), exist_ok=True)
|
||||
|
||||
if not os.path.isfile(CONFIG_FILE) or os.stat(CONFIG_FILE).st_size == 0:
|
||||
write_config(get_default_settings())
|
||||
write_settings(get_default_settings())
|
||||
|
||||
with open(CONFIG_FILE, "r") as config_file:
|
||||
return json.load(config_file)
|
||||
|
||||
|
||||
def write_config(config):
|
||||
def write_settings(config):
|
||||
with open(CONFIG_FILE, "w") as config_file:
|
||||
json.dump(config, config_file, indent=" ")
|
||||
|
||||
|
||||
def get_default_settings():
|
||||
return {
|
||||
Profile.ENIGMA_2.value: {
|
||||
"host": "127.0.0.1", "port": "21", "user": "root", "password": "root",
|
||||
"http_user": "root", "http_password": "", "http_port": "80", "http_timeout": 5,
|
||||
"telnet_user": "root", "telnet_password": "", "telnet_port": "23", "telnet_timeout": 5,
|
||||
"services_path": "/etc/enigma2/", "user_bouquet_path": "/etc/enigma2/",
|
||||
"satellites_xml_path": "/etc/tuxbox/", "data_dir_path": DATA_PATH + "enigma2/",
|
||||
"picons_path": "/usr/share/enigma2/picon", "picons_dir_path": DATA_PATH + "enigma2/picons/",
|
||||
"backup_dir_path": DATA_PATH + "enigma2/backup/",
|
||||
"backup_before_save": True, "backup_before_downloading": True,
|
||||
"v5_support": False, "http_api_support": False, "enable_yt_dl": False, "enable_send_to": False,
|
||||
"use_colors": True, "new_color": "rgb(255,230,204)", "extra_color": "rgb(179,230,204)",
|
||||
"fav_click_mode": 0},
|
||||
Profile.NEUTRINO_MP.value: {
|
||||
"host": "127.0.0.1", "port": "21", "user": "root", "password": "root",
|
||||
"http_user": "", "http_password": "", "http_port": "80", "http_timeout": 2,
|
||||
"telnet_user": "root", "telnet_password": "", "telnet_port": "23", "telnet_timeout": 1,
|
||||
"services_path": "/var/tuxbox/config/zapit/", "user_bouquet_path": "/var/tuxbox/config/zapit/",
|
||||
"satellites_xml_path": "/var/tuxbox/config/", "data_dir_path": DATA_PATH + "neutrino/",
|
||||
"picons_path": "/usr/share/tuxbox/neutrino/icons/logo/", "picons_dir_path": DATA_PATH + "neutrino/picons/",
|
||||
"backup_dir_path": DATA_PATH + "neutrino/backup/",
|
||||
"backup_before_save": True, "backup_before_downloading": True,
|
||||
"fav_click_mode": 0},
|
||||
"profile": Profile.ENIGMA_2.value}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
|
||||
@@ -7,7 +7,7 @@ from collections import namedtuple
|
||||
from html.parser import HTMLParser
|
||||
|
||||
from app.commons import run_task
|
||||
from app.settings import Profile
|
||||
from app.settings import SettingsType
|
||||
|
||||
_ENIGMA2_PICON_KEY = "{:X}:{:X}:{}"
|
||||
_NEUTRINO_PICON_KEY = "{:x}{:04x}{:04x}.png"
|
||||
@@ -79,7 +79,7 @@ class PiconsParser(HTMLParser):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def parse(open_path, picons_path, tmp_path, provider, picon_ids, profile=Profile.ENIGMA_2):
|
||||
def parse(open_path, picons_path, tmp_path, provider, picon_ids, s_type=SettingsType.ENIGMA_2):
|
||||
with open(open_path, encoding="utf-8", errors="replace") as f:
|
||||
on_id, pos, ssid, single = provider.on_id, provider.pos, provider.ssid, provider.single
|
||||
neg_pos = pos.endswith("W")
|
||||
@@ -100,7 +100,7 @@ class PiconsParser(HTMLParser):
|
||||
namespace = "{:X}{:X}".format(int(pos), int(freq))
|
||||
else:
|
||||
namespace = "{:X}0000".format(int(pos))
|
||||
name = PiconsParser.format(ssid if single else p.ssid, on_id, namespace, picon_ids, profile)
|
||||
name = PiconsParser.format(ssid if single else p.ssid, on_id, namespace, picon_ids, s_type)
|
||||
p_name = picons_path + (name if name else os.path.basename(p.ref))
|
||||
shutil.copyfile(tmp_path + "www.lyngsat.com/" + p.ref.lstrip("."), p_name)
|
||||
except (TypeError, ValueError) as e:
|
||||
@@ -109,10 +109,10 @@ class PiconsParser(HTMLParser):
|
||||
print(msg)
|
||||
|
||||
@staticmethod
|
||||
def format(ssid, on_id, namespace, picon_ids, profile: Profile):
|
||||
if profile is Profile.ENIGMA_2:
|
||||
def format(ssid, on_id, namespace, picon_ids, s_type):
|
||||
if s_type is SettingsType.ENIGMA_2:
|
||||
return picon_ids.get(_ENIGMA2_PICON_KEY.format(int(ssid), int(on_id), namespace), None)
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
elif s_type is SettingsType.NEUTRINO_MP:
|
||||
tr_id = int(ssid[:-2] if len(ssid) < 4 else ssid[:2])
|
||||
return _NEUTRINO_PICON_KEY.format(tr_id, int(on_id), int(ssid))
|
||||
else:
|
||||
@@ -249,12 +249,12 @@ def parse_providers(open_path):
|
||||
|
||||
|
||||
@run_task
|
||||
def convert_to(src_path, dest_path, profile, callback, done_callback):
|
||||
def convert_to(src_path, dest_path, s_type, callback, done_callback):
|
||||
""" Converts names format of picons.
|
||||
|
||||
Copies resulting files from src to dest and writes state to callback.
|
||||
"""
|
||||
pattern = "/*_0_0_0.png" if profile is Profile.ENIGMA_2 else "/*.png"
|
||||
pattern = "/*_0_0_0.png" if s_type is SettingsType.ENIGMA_2 else "/*.png"
|
||||
for file in glob.glob(src_path + pattern):
|
||||
base_name = os.path.basename(file)
|
||||
pic_data = base_name.rstrip(".png").split("_")
|
||||
|
||||
@@ -7,7 +7,7 @@ from datetime import datetime
|
||||
from enum import Enum
|
||||
|
||||
from app.commons import run_idle
|
||||
from app.settings import Profile
|
||||
from app.settings import SettingsType
|
||||
from app.ui.dialogs import show_dialog, DialogType
|
||||
from app.ui.main_helper import append_text_to_tview
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, KeyboardKey
|
||||
@@ -36,9 +36,9 @@ class BackupDialog:
|
||||
builder.connect_signals(handlers)
|
||||
|
||||
self._settings = settings
|
||||
self._profile = settings.profile
|
||||
self._data_path = self._settings.data_dir_path
|
||||
self._backup_path = self._settings.backup_dir_path or self._data_path + "backup/"
|
||||
self._s_type = settings.setting_type
|
||||
self._data_path = self._settings.data_local_path
|
||||
self._backup_path = self._settings.backup_local_path or self._data_path + "backup/"
|
||||
self._open_data_callback = callback
|
||||
self._dialog_window = builder.get_object("dialog_window")
|
||||
self._dialog_window.set_transient_for(transient)
|
||||
@@ -152,7 +152,7 @@ class BackupDialog:
|
||||
shutil.unpack_archive(full_file_name, self._data_path)
|
||||
elif restore_type is RestoreType.BOUQUETS:
|
||||
tmp_dir = tempfile.gettempdir() + "/" + file_name
|
||||
cond = (".tv", ".radio") if self._profile is Profile.ENIGMA_2 else "bouquets.xml"
|
||||
cond = (".tv", ".radio") if self._s_type is SettingsType.ENIGMA_2 else "bouquets.xml"
|
||||
shutil.unpack_archive(full_file_name, tmp_dir)
|
||||
for file in filter(lambda f: f.endswith(cond), os.listdir(self._data_path)):
|
||||
os.remove(os.path.join(self._data_path, file))
|
||||
|
||||
@@ -101,7 +101,7 @@ def get_file_chooser_dialog(transient, text, settings, action_type, file_filter)
|
||||
if file_filter is not None:
|
||||
dialog.add_filter(file_filter)
|
||||
|
||||
path = settings.data_dir_path
|
||||
path = settings.data_local_path
|
||||
dialog.set_current_folder(path)
|
||||
response = dialog.run()
|
||||
if response == Gtk.ResponseType.OK:
|
||||
|
||||
@@ -2,7 +2,7 @@ from gi.repository import GLib
|
||||
|
||||
from app.commons import run_idle, run_task
|
||||
from app.connections import download_data, DownloadType, upload_data
|
||||
from app.settings import Profile
|
||||
from app.settings import SettingsType
|
||||
from app.ui.backup import backup_data, restore_data
|
||||
from app.ui.main_helper import append_text_to_tview
|
||||
from app.ui.settings_dialog import show_settings_dialog
|
||||
@@ -12,7 +12,7 @@ from .dialogs import show_dialog, DialogType, get_message
|
||||
|
||||
class DownloadDialog:
|
||||
def __init__(self, transient, settings, open_data_callback, update_settings_callback):
|
||||
self._profile = settings.profile
|
||||
self._s_type = settings.setting_type
|
||||
self._settings = settings
|
||||
self._open_data_callback = open_data_callback
|
||||
self._update_settings_callback = update_settings_callback
|
||||
@@ -59,8 +59,8 @@ class DownloadDialog:
|
||||
|
||||
def init_settings(self):
|
||||
self._host_entry.set_text(self._settings.host)
|
||||
self._data_path_entry.set_text(self._settings.data_dir_path)
|
||||
is_enigma = self._profile is Profile.ENIGMA_2
|
||||
self._data_path_entry.set_text(self._settings.data_local_path)
|
||||
is_enigma = self._s_type is SettingsType.ENIGMA_2
|
||||
self._webtv_radio_button.set_visible(not is_enigma)
|
||||
self._http_radio_button.set_visible(is_enigma)
|
||||
self._use_http_box.set_visible(is_enigma)
|
||||
@@ -111,7 +111,7 @@ class DownloadDialog:
|
||||
def on_preferences(self, item):
|
||||
response = show_settings_dialog(self._dialog_window, self._settings)
|
||||
if response != Gtk.ResponseType.CANCEL:
|
||||
self._profile = self._settings.profile
|
||||
self._s_type = self._settings.setting_type
|
||||
self.init_settings()
|
||||
gen = self._update_settings_callback()
|
||||
GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
|
||||
@@ -134,8 +134,8 @@ class DownloadDialog:
|
||||
try:
|
||||
if download:
|
||||
if backup and d_type is not DownloadType.SATELLITES:
|
||||
data_path = self._settings.data_dir_path or self._data_path_entry.get_text()
|
||||
backup_path = self._settings.backup_dir_path or data_path + "backup/"
|
||||
data_path = self._settings.data_local_path or self._data_path_entry.get_text()
|
||||
backup_path = self._settings.backup_local_path or data_path + "backup/"
|
||||
backup_src = backup_data(data_path, backup_path, d_type is DownloadType.ALL)
|
||||
download_data(settings=self._settings, download_type=d_type, callback=self.append_output)
|
||||
else:
|
||||
|
||||
@@ -483,7 +483,7 @@ class EpgDialog:
|
||||
# ***************** Options *********************#
|
||||
|
||||
def init_options(self):
|
||||
epg_dat_path = self._settings.data_dir_path + "epg/"
|
||||
epg_dat_path = self._settings.data_local_path + "epg/"
|
||||
self._epg_dat_path_entry.set_text(epg_dat_path)
|
||||
default_epg_data_stb_path = "/etc/enigma2"
|
||||
epg_options = self._settings.get("epg_options")
|
||||
|
||||
@@ -6,7 +6,7 @@ from app.eparser import get_bouquets, get_services
|
||||
from app.eparser.ecommons import BqType, BqServiceType, Bouquet
|
||||
from app.eparser.enigma.bouquets import get_bouquet
|
||||
from app.eparser.neutrino.bouquets import parse_webtv, parse_bouquets as get_neutrino_bouquets
|
||||
from app.settings import Profile
|
||||
from app.settings import SettingsType
|
||||
from app.ui.dialogs import show_dialog, DialogType, get_chooser_dialog, get_message
|
||||
from app.ui.main_helper import on_popup_menu
|
||||
from .uicommons import Gtk, UI_RESOURCES_PATH, KeyboardKey, Column
|
||||
@@ -17,12 +17,12 @@ def import_bouquet(transient, model, path, settings, services, appender):
|
||||
itr = model.get_iter(path)
|
||||
bq_type = BqType(model.get(itr, Column.BQ_TYPE)[0])
|
||||
pattern, f_pattern = None, None
|
||||
profile = settings.profile
|
||||
profile = settings.setting_type
|
||||
|
||||
if profile is Profile.ENIGMA_2:
|
||||
if profile is SettingsType.ENIGMA_2:
|
||||
pattern = ".{}".format(bq_type.value)
|
||||
f_pattern = "userbouquet.*{}".format(pattern)
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
elif profile is SettingsType.NEUTRINO_MP:
|
||||
pattern = "webtv.xml" if bq_type is BqType.WEBTV else "bouquets.xml"
|
||||
f_pattern = "bouquets.xml"
|
||||
if bq_type is BqType.TV:
|
||||
@@ -38,7 +38,7 @@ def import_bouquet(transient, model, path, settings, services, appender):
|
||||
show_dialog(DialogType.ERROR, transient, text="No bouquet file is selected!")
|
||||
return
|
||||
|
||||
if profile is Profile.ENIGMA_2:
|
||||
if profile is SettingsType.ENIGMA_2:
|
||||
bq = get_enigma2_bouquet(file_path)
|
||||
imported = list(filter(lambda x: x.data in services or x.type is BqServiceType.IPTV, bq.services))
|
||||
|
||||
@@ -51,7 +51,7 @@ def import_bouquet(transient, model, path, settings, services, appender):
|
||||
else:
|
||||
p_itr = model.iter_parent(itr)
|
||||
appender(bq, p_itr) if p_itr else appender(bq, itr)
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
elif profile is SettingsType.NEUTRINO_MP:
|
||||
if bq_type is BqType.WEBTV:
|
||||
bqs = parse_webtv(file_path, "WEBTV", bq_type.value)
|
||||
else:
|
||||
@@ -90,7 +90,7 @@ class ImportDialog:
|
||||
self._services = {}
|
||||
self._service_ids = service_ids
|
||||
self._append = appender
|
||||
self._profile = settings.profile
|
||||
self._profile = settings.setting_type
|
||||
self._settings = settings
|
||||
self._bouquets = bouquets
|
||||
|
||||
@@ -125,7 +125,7 @@ class ImportDialog:
|
||||
self._main_model.append((bq.name, bq.type, True))
|
||||
self._bq_services[(bq.name, bq.type)] = bq.services
|
||||
# Note! Getting default format ver. 4
|
||||
services = get_services(path, self._profile, 4 if self._profile is Profile.ENIGMA_2 else 0)
|
||||
services = get_services(path, self._profile, 4 if self._profile is SettingsType.ENIGMA_2 else 0)
|
||||
for srv in services:
|
||||
self._services[srv.fav_id] = srv
|
||||
except FileNotFoundError as e:
|
||||
|
||||
@@ -13,7 +13,7 @@ from gi.repository import GLib
|
||||
from app.commons import run_idle, run_task, log
|
||||
from app.eparser.ecommons import BqServiceType, Service
|
||||
from app.eparser.iptv import NEUTRINO_FAV_ID_FORMAT, StreamType, ENIGMA2_FAV_ID_FORMAT, get_fav_id, MARKER_FORMAT
|
||||
from app.settings import Profile
|
||||
from app.settings import SettingsType
|
||||
from app.tools.yt import YouTube, PlayListParser
|
||||
from .dialogs import Action, show_dialog, DialogType, get_dialogs_string, get_message
|
||||
from .main_helper import get_base_model, get_iptv_url, on_popup_menu
|
||||
@@ -61,7 +61,7 @@ def get_yt_icon(icon_name, size=24):
|
||||
|
||||
class IptvDialog:
|
||||
|
||||
def __init__(self, transient, view, services, bouquet, profile=Profile.ENIGMA_2, action=Action.ADD):
|
||||
def __init__(self, transient, view, services, bouquet, profile=SettingsType.ENIGMA_2, action=Action.ADD):
|
||||
handlers = {"on_response": self.on_response,
|
||||
"on_entry_changed": self.on_entry_changed,
|
||||
"on_url_changed": self.on_url_changed,
|
||||
@@ -109,7 +109,7 @@ class IptvDialog:
|
||||
for el in self._digit_elems:
|
||||
el.get_style_context().add_provider_for_screen(Gdk.Screen.get_default(), self._style_provider,
|
||||
Gtk.STYLE_PROVIDER_PRIORITY_USER)
|
||||
if profile is Profile.NEUTRINO_MP:
|
||||
if profile is SettingsType.NEUTRINO_MP:
|
||||
builder.get_object("iptv_dialog_ts_data_frame").set_visible(False)
|
||||
builder.get_object("iptv_type_label").set_visible(False)
|
||||
builder.get_object("reference_entry").set_visible(False)
|
||||
@@ -122,7 +122,7 @@ class IptvDialog:
|
||||
if self._action is Action.ADD:
|
||||
self._save_button.set_visible(False)
|
||||
self._add_button.set_visible(True)
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
if self._profile is SettingsType.ENIGMA_2:
|
||||
self._update_reference_entry()
|
||||
self._stream_type_combobox.set_active(1)
|
||||
elif self._action is Action.EDIT:
|
||||
@@ -147,13 +147,13 @@ class IptvDialog:
|
||||
if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL:
|
||||
return
|
||||
|
||||
self.save_enigma2_data() if self._profile is Profile.ENIGMA_2 else self.save_neutrino_data()
|
||||
self.save_enigma2_data() if self._profile is SettingsType.ENIGMA_2 else self.save_neutrino_data()
|
||||
self._dialog.destroy()
|
||||
|
||||
def init_data(self, srv):
|
||||
name, fav_id = srv[2], srv[7]
|
||||
self._name_entry.set_text(name)
|
||||
self.init_enigma2_data(fav_id) if self._profile is Profile.ENIGMA_2 else self.init_neutrino_data(fav_id)
|
||||
self.init_enigma2_data(fav_id) if self._profile is SettingsType.ENIGMA_2 else self.init_neutrino_data(fav_id)
|
||||
|
||||
def init_enigma2_data(self, fav_id):
|
||||
data, sep, desc = fav_id.partition("#DESCRIPTION")
|
||||
@@ -190,7 +190,7 @@ class IptvDialog:
|
||||
self._description_entry.set_text(data[1])
|
||||
|
||||
def _update_reference_entry(self):
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
if self._profile is SettingsType.ENIGMA_2:
|
||||
self._reference_entry.set_text(_ENIGMA2_REFERENCE.format(self.get_type(),
|
||||
self._srv_type_entry.get_text(),
|
||||
int(self._sid_entry.get_text()),
|
||||
@@ -505,7 +505,7 @@ class IptvListConfigurationDialog:
|
||||
show_dialog(DialogType.ERROR, self._dialog, "Error. Verify the data!")
|
||||
return
|
||||
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
if self._profile is SettingsType.ENIGMA_2:
|
||||
reset = self._reset_to_default_switch.get_active()
|
||||
type_default = self._type_check_button.get_active()
|
||||
tid_default = self._tid_check_button.get_active()
|
||||
|
||||
@@ -16,7 +16,7 @@ from app.eparser.ecommons import CAS, Flag, BouquetService
|
||||
from app.eparser.enigma.bouquets import BqServiceType
|
||||
from app.eparser.iptv import export_to_m3u
|
||||
from app.eparser.neutrino.bouquets import BqType
|
||||
from app.settings import Profile, Settings
|
||||
from app.settings import SettingsType, Settings, SettingsException
|
||||
from app.tools.media import Player
|
||||
from app.ui.epg_dialog import EpgDialog
|
||||
from app.ui.transmitter import LinksTransmitter
|
||||
@@ -158,8 +158,8 @@ class Application(Gtk.Application):
|
||||
"on_create_bouquet_for_each_type": self.on_create_bouquet_for_each_type}
|
||||
|
||||
self._settings = Settings.get_instance()
|
||||
self._profile = self._settings.profile
|
||||
os.makedirs(os.path.dirname(self._settings.data_dir_path), exist_ok=True)
|
||||
self._s_type = self._settings.setting_type
|
||||
os.makedirs(os.path.dirname(self._settings.data_local_path), exist_ok=True)
|
||||
# Used for copy/paste. When adding the previous data will not be deleted.
|
||||
# Clearing only after the insertion!
|
||||
self._rows_buffer = []
|
||||
@@ -188,7 +188,6 @@ class Application(Gtk.Application):
|
||||
self._EXTRA_COLOR = None # Color for services with a extra name for the bouquet
|
||||
|
||||
builder = Gtk.Builder()
|
||||
builder.set_translation_domain("demon-editor")
|
||||
builder.add_from_file(UI_RESOURCES_PATH + "main_window.glade")
|
||||
builder.connect_signals(handlers)
|
||||
self._main_window = builder.get_object("main_window")
|
||||
@@ -215,8 +214,8 @@ class Application(Gtk.Application):
|
||||
self._app_info_box.bind_property("visible", builder.get_object("right_header_box"), "sensitive", 4)
|
||||
self._app_info_box.bind_property("visible", builder.get_object("left_header_box"), "sensitive", 4)
|
||||
# Status bar
|
||||
self._ip_label = builder.get_object("ip_label")
|
||||
self._ip_label.set_text(self._settings.host)
|
||||
self._profile_combo_box = builder.get_object("profile_combo_box")
|
||||
self._profile_combo_box.set_tooltip_text(self._profile_combo_box.get_tooltip_text() + self._settings.host)
|
||||
self._receiver_info_box = builder.get_object("receiver_info_box")
|
||||
self._receiver_info_label = builder.get_object("receiver_info_label")
|
||||
self._signal_box = builder.get_object("signal_box")
|
||||
@@ -343,7 +342,7 @@ class Application(Gtk.Application):
|
||||
|
||||
If update=False - first call on program start, else - after options changes!
|
||||
"""
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
if self._settings.use_colors:
|
||||
new_rgb = Gdk.RGBA()
|
||||
extra_rgb = Gdk.RGBA()
|
||||
@@ -574,7 +573,7 @@ class Application(Gtk.Application):
|
||||
# ***************** ####### *********************#
|
||||
|
||||
def get_bouquet_file_name(self, bouquet):
|
||||
bouquet_file_name = "{}userbouquet.{}.{}".format(self._settings.get(self._profile).get("data_dir_path"),
|
||||
bouquet_file_name = "{}userbouquet.{}.{}".format(self._settings.get(self._s_type).get("data_dir_path"),
|
||||
*bouquet.split(":"))
|
||||
return bouquet_file_name
|
||||
|
||||
@@ -824,11 +823,11 @@ class Application(Gtk.Application):
|
||||
@run_task
|
||||
def on_upload_data(self, download_type):
|
||||
try:
|
||||
profile = self._profile
|
||||
profile = self._s_type
|
||||
opts = self._settings
|
||||
use_http = profile is Profile.ENIGMA_2
|
||||
use_http = profile is SettingsType.ENIGMA_2
|
||||
|
||||
if profile is Profile.ENIGMA_2:
|
||||
if profile is SettingsType.ENIGMA_2:
|
||||
host, port, user, password = opts.host, opts.http_port, opts.http_user, opts.http_password
|
||||
try:
|
||||
test_http(host, port, user, password, skip_message=True)
|
||||
@@ -858,17 +857,17 @@ class Application(Gtk.Application):
|
||||
self._wait_dialog.show()
|
||||
yield True
|
||||
|
||||
data_path = self._settings.data_dir_path if data_path is None else data_path
|
||||
data_path = self._settings.data_local_path if data_path is None else data_path
|
||||
yield from self.clear_current_data()
|
||||
|
||||
try:
|
||||
prf = self._profile
|
||||
prf = self._s_type
|
||||
black_list = get_blacklist(data_path)
|
||||
bouquets = get_bouquets(data_path, prf)
|
||||
yield True
|
||||
services = get_services(data_path, prf, self.get_format_version() if prf is Profile.ENIGMA_2 else 0)
|
||||
services = get_services(data_path, prf, self.get_format_version() if prf is SettingsType.ENIGMA_2 else 0)
|
||||
yield True
|
||||
update_picons_data(self._settings.picons_dir_path, self._picons)
|
||||
update_picons_data(self._settings.picons_local_path, self._picons)
|
||||
yield True
|
||||
except FileNotFoundError as e:
|
||||
msg = get_message("Please, download files from receiver or setup your path for read data!")
|
||||
@@ -1009,9 +1008,9 @@ class Application(Gtk.Application):
|
||||
|
||||
def save_data(self):
|
||||
self._save_header_button.set_sensitive(False)
|
||||
profile = self._profile
|
||||
path = self._settings.data_dir_path
|
||||
backup_path = self._settings.backup_dir_path
|
||||
profile = self._s_type
|
||||
path = self._settings.data_local_path
|
||||
backup_path = self._settings.backup_local_path
|
||||
# Backup data or clearing data path
|
||||
backup_data(path, backup_path) if self._settings.backup_before_save else clear_data_path(path)
|
||||
yield True
|
||||
@@ -1031,7 +1030,7 @@ class Application(Gtk.Application):
|
||||
favs = self._bouquets[bq_id]
|
||||
ex_s = self._extra_bouquets.get(bq_id)
|
||||
bq_s = list(filter(None, [self._services.get(f_id, None) for f_id in favs]))
|
||||
if profile is Profile.ENIGMA_2:
|
||||
if profile is SettingsType.ENIGMA_2:
|
||||
bq_s = list(map(lambda s: s._replace(service=ex_s.get(s.fav_id, None) if ex_s else None), bq_s))
|
||||
bq = Bouquet(bq_name, bq_type, bq_s, locked, hidden)
|
||||
bqs.append(bq)
|
||||
@@ -1045,10 +1044,10 @@ class Application(Gtk.Application):
|
||||
# Getting services
|
||||
services_model = get_base_model(self._services_view.get_model())
|
||||
services = [Service(*row[: Column.SRV_TOOLTIP]) for row in services_model]
|
||||
write_services(path, services, profile, self.get_format_version() if profile is Profile.ENIGMA_2 else 0)
|
||||
write_services(path, services, profile, self.get_format_version() if profile is SettingsType.ENIGMA_2 else 0)
|
||||
yield True
|
||||
# removing bouquet files
|
||||
if profile is Profile.ENIGMA_2:
|
||||
if profile is SettingsType.ENIGMA_2:
|
||||
# blacklist
|
||||
write_blacklist(path, self._blacklist)
|
||||
|
||||
@@ -1060,7 +1059,7 @@ class Application(Gtk.Application):
|
||||
if show_dialog(DialogType.QUESTION, self._main_window) == Gtk.ResponseType.CANCEL:
|
||||
return
|
||||
|
||||
gen = self.create_new_configuration(self._profile)
|
||||
gen = self.create_new_configuration(self._s_type)
|
||||
GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
|
||||
|
||||
def create_new_configuration(self, profile):
|
||||
@@ -1070,12 +1069,12 @@ class Application(Gtk.Application):
|
||||
c_gen = self.clear_current_data()
|
||||
yield from c_gen
|
||||
|
||||
if profile is Profile.ENIGMA_2:
|
||||
if profile is SettingsType.ENIGMA_2:
|
||||
parent = self._bouquets_model.append(None, ["Favourites (TV)", None, None, BqType.TV.value])
|
||||
self.append_bouquet(Bouquet("Favourites (TV)", BqType.TV.value, [], None, None), parent)
|
||||
parent = self._bouquets_model.append(None, ["Favourites (Radio)", None, None, BqType.RADIO.value])
|
||||
self.append_bouquet(Bouquet("Favourites (Radio)", BqType.RADIO.value, [], None, None), parent)
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
elif profile is SettingsType.NEUTRINO_MP:
|
||||
self._bouquets_model.append(None, ["Providers", None, None, BqType.BOUQUET.value])
|
||||
self._bouquets_model.append(None, ["FAV", None, None, BqType.TV.value])
|
||||
self._bouquets_model.append(None, ["WEBTV", None, None, BqType.WEBTV.value])
|
||||
@@ -1143,7 +1142,7 @@ class Application(Gtk.Application):
|
||||
self.show_error_dialog("Error. No bouquet is selected!")
|
||||
return
|
||||
|
||||
if self._profile is Profile.NEUTRINO_MP and self._bq_selected.endswith(BqType.WEBTV.value):
|
||||
if self._s_type is SettingsType.NEUTRINO_MP and self._bq_selected.endswith(BqType.WEBTV.value):
|
||||
self.show_error_dialog("Operation not allowed in this context!")
|
||||
return
|
||||
|
||||
@@ -1175,11 +1174,11 @@ class Application(Gtk.Application):
|
||||
GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
|
||||
|
||||
def update_options(self):
|
||||
profile = self._settings.profile
|
||||
self._ip_label.set_text(self._settings.host)
|
||||
if profile != self._profile:
|
||||
profile = self._settings.setting_type
|
||||
|
||||
if profile != self._s_type:
|
||||
yield from self.show_app_info(True)
|
||||
self._profile = profile
|
||||
self._s_type = profile
|
||||
c_gen = self.clear_current_data()
|
||||
yield from c_gen
|
||||
self.update_profile_label()
|
||||
@@ -1284,7 +1283,7 @@ class Application(Gtk.Application):
|
||||
self._tool_elements[elem].set_sensitive(not_empty)
|
||||
if elem == "bouquets_paste_popup_item":
|
||||
self._tool_elements[elem].set_sensitive(not_empty and self._bouquets_buffer)
|
||||
if self._profile is Profile.NEUTRINO_MP:
|
||||
if self._s_type is SettingsType.NEUTRINO_MP:
|
||||
for elem in self._LOCK_HIDE_ELEMENTS:
|
||||
self._tool_elements[elem].set_sensitive(not_empty)
|
||||
else:
|
||||
@@ -1300,17 +1299,17 @@ class Application(Gtk.Application):
|
||||
for elem in self._BOUQUET_ELEMENTS:
|
||||
self._tool_elements[elem].set_sensitive(False)
|
||||
for elem in self._LOCK_HIDE_ELEMENTS:
|
||||
self._tool_elements[elem].set_sensitive(not_empty and self._profile is Profile.ENIGMA_2)
|
||||
self._tool_elements[elem].set_sensitive(not_empty and self._s_type is SettingsType.ENIGMA_2)
|
||||
|
||||
for elem in self._FAV_IPTV_ELEMENTS:
|
||||
is_iptv = self._bq_selected and not is_service
|
||||
if self._profile is Profile.NEUTRINO_MP:
|
||||
if self._s_type is SettingsType.NEUTRINO_MP:
|
||||
is_iptv = is_iptv and BqType(self._bq_selected.split(":")[1]) is BqType.WEBTV
|
||||
self._tool_elements[elem].set_sensitive(is_iptv)
|
||||
for elem in self._COMMONS_ELEMENTS:
|
||||
self._tool_elements[elem].set_sensitive(not_empty)
|
||||
|
||||
if self._profile is not Profile.ENIGMA_2:
|
||||
if self._s_type is not SettingsType.ENIGMA_2:
|
||||
for elem in self._FAV_ENIGMA_ELEMENTS:
|
||||
self._tool_elements[elem].set_sensitive(False)
|
||||
|
||||
@@ -1321,9 +1320,9 @@ class Application(Gtk.Application):
|
||||
self.set_service_flags(Flag.LOCK)
|
||||
|
||||
def set_service_flags(self, flag):
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
set_flags(flag, self._services_view, self._fav_view, self._services, self._blacklist)
|
||||
elif self._profile is Profile.NEUTRINO_MP and self._bq_selected:
|
||||
elif self._s_type is SettingsType.NEUTRINO_MP and self._bq_selected:
|
||||
model, paths = self._bouquets_view.get_selection().get_selected_rows()
|
||||
itr = model.get_iter(paths[0])
|
||||
value = model.get_value(itr, 1 if flag is Flag.LOCK else 2)
|
||||
@@ -1386,14 +1385,14 @@ class Application(Gtk.Application):
|
||||
self._fav_view,
|
||||
self._services,
|
||||
self._bouquets.get(self._bq_selected, None),
|
||||
self._profile,
|
||||
self._s_type,
|
||||
Action.ADD).show()
|
||||
if response != Gtk.ResponseType.CANCEL:
|
||||
self.update_fav_num_column(self._fav_model)
|
||||
|
||||
@run_idle
|
||||
def on_iptv_list_configuration(self, item):
|
||||
if self._profile is Profile.NEUTRINO_MP:
|
||||
if self._s_type is SettingsType.NEUTRINO_MP:
|
||||
self.show_error_dialog("Neutrino at the moment not supported!")
|
||||
return
|
||||
|
||||
@@ -1407,7 +1406,7 @@ class Application(Gtk.Application):
|
||||
|
||||
bq = self._bouquets.get(self._bq_selected, [])
|
||||
IptvListConfigurationDialog(self._main_window, self._services, iptv_rows, bq,
|
||||
self._fav_model, self._profile).show()
|
||||
self._fav_model, self._s_type).show()
|
||||
|
||||
@run_idle
|
||||
def on_remove_all_unavailable(self, item):
|
||||
@@ -1423,7 +1422,7 @@ class Application(Gtk.Application):
|
||||
return
|
||||
|
||||
fav_bqt = self._bouquets.get(self._bq_selected, None)
|
||||
response = SearchUnavailableDialog(self._main_window, self._fav_model, fav_bqt, iptv_rows, self._profile).show()
|
||||
response = SearchUnavailableDialog(self._main_window, self._fav_model, fav_bqt, iptv_rows, self._s_type).show()
|
||||
if response:
|
||||
next(self.remove_favs(response, self._fav_model), False)
|
||||
|
||||
@@ -1431,7 +1430,7 @@ class Application(Gtk.Application):
|
||||
|
||||
@run_idle
|
||||
def on_epg_list_configuration(self, item):
|
||||
if self._profile is not Profile.ENIGMA_2:
|
||||
if self._s_type is not SettingsType.ENIGMA_2:
|
||||
self.show_error_dialog("Only Enigma2 is supported!")
|
||||
return
|
||||
|
||||
@@ -1449,7 +1448,7 @@ class Application(Gtk.Application):
|
||||
if not self._bq_selected:
|
||||
return
|
||||
|
||||
YtListImportDialog(self._main_window, self._profile, self.append_imported_services).show()
|
||||
YtListImportDialog(self._main_window, self._s_type, self.append_imported_services).show()
|
||||
|
||||
def on_import_m3u(self, item):
|
||||
""" Imports iptv from m3u files. """
|
||||
@@ -1461,7 +1460,7 @@ class Application(Gtk.Application):
|
||||
self.show_error_dialog("No m3u file is selected!")
|
||||
return
|
||||
|
||||
channels = parse_m3u(response, self._profile)
|
||||
channels = parse_m3u(response, self._s_type)
|
||||
|
||||
if channels and self._bq_selected:
|
||||
self.append_imported_services(channels)
|
||||
@@ -1492,7 +1491,7 @@ class Application(Gtk.Application):
|
||||
|
||||
try:
|
||||
bq = Bouquet(self._current_bq_name, None, bq_services, None, None)
|
||||
export_to_m3u(response, bq, self._profile)
|
||||
export_to_m3u(response, bq, self._s_type)
|
||||
except Exception as e:
|
||||
self.show_error_dialog(str(e))
|
||||
else:
|
||||
@@ -1504,7 +1503,7 @@ class Application(Gtk.Application):
|
||||
self.show_error_dialog("No selected item!")
|
||||
return
|
||||
|
||||
appender = self.append_bouquet if self._profile is Profile.ENIGMA_2 else self.append_bouquets
|
||||
appender = self.append_bouquet if self._s_type is SettingsType.ENIGMA_2 else self.append_bouquets
|
||||
import_bouquet(self._main_window, model, paths[0], self._settings, self._services, appender)
|
||||
|
||||
def on_import_bouquets(self, item):
|
||||
@@ -1545,7 +1544,7 @@ class Application(Gtk.Application):
|
||||
self.show_error_dialog("Not allowed in this context!")
|
||||
return
|
||||
|
||||
url = get_iptv_url(row, self._profile)
|
||||
url = get_iptv_url(row, self._s_type)
|
||||
self.update_player_buttons()
|
||||
if not url:
|
||||
return
|
||||
@@ -1659,10 +1658,11 @@ class Application(Gtk.Application):
|
||||
def init_http_api(self):
|
||||
self._fav_click_mode = FavClickMode(self._settings.fav_click_mode)
|
||||
http_api_enable = self._settings.http_api_support
|
||||
status = all((http_api_enable, self._profile is Profile.ENIGMA_2, not self._receiver_info_box.get_visible()))
|
||||
status = all(
|
||||
(http_api_enable, self._s_type is SettingsType.ENIGMA_2, not self._receiver_info_box.get_visible()))
|
||||
GLib.idle_add(self._http_status_image.set_visible, status)
|
||||
|
||||
if self._profile is Profile.NEUTRINO_MP or not http_api_enable:
|
||||
if self._s_type is SettingsType.NEUTRINO_MP or not http_api_enable:
|
||||
self.update_info_boxes_visible(False)
|
||||
if self._http_api:
|
||||
self._http_api.close()
|
||||
@@ -1786,7 +1786,7 @@ class Application(Gtk.Application):
|
||||
self._sat_positions.clear()
|
||||
sat_positions = set()
|
||||
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
terrestrial = False
|
||||
cable = False
|
||||
|
||||
@@ -1803,7 +1803,7 @@ class Application(Gtk.Application):
|
||||
self._sat_positions.append("T")
|
||||
if cable:
|
||||
self._sat_positions.append("C")
|
||||
elif self._profile is Profile.NEUTRINO_MP:
|
||||
elif self._s_type is SettingsType.NEUTRINO_MP:
|
||||
list(map(lambda s: sat_positions.add(float(s.pos)), filter(lambda s: s.pos, self._services.values())))
|
||||
|
||||
self._sat_positions.extend(map(str, sorted(sat_positions)))
|
||||
@@ -1881,7 +1881,7 @@ class Application(Gtk.Application):
|
||||
self._fav_view,
|
||||
self._services,
|
||||
self._bouquets.get(self._bq_selected, None),
|
||||
self._profile,
|
||||
self._s_type,
|
||||
Action.EDIT).show()
|
||||
self.on_locate_in_services(view)
|
||||
|
||||
@@ -1999,7 +1999,7 @@ class Application(Gtk.Application):
|
||||
@run_idle
|
||||
def on_picons_loader_show(self, item):
|
||||
ids = {}
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
for r in self._services_model:
|
||||
data = r[Column.SRV_PICON_ID].split("_")
|
||||
ids["{}:{}:{}".format(data[3], data[5], data[6])] = r[Column.SRV_PICON_ID]
|
||||
@@ -2009,7 +2009,7 @@ class Application(Gtk.Application):
|
||||
|
||||
@run_task
|
||||
def update_picons(self):
|
||||
update_picons_data(self._settings.picons_dir_path, self._picons)
|
||||
update_picons_data(self._settings.picons_local_path, self._picons)
|
||||
append_picons(self._picons, self._services_model)
|
||||
|
||||
def on_assign_picon(self, view):
|
||||
@@ -2062,15 +2062,20 @@ class Application(Gtk.Application):
|
||||
|
||||
def create_bouquets(self, g_type):
|
||||
gen_bouquets(self._services_view, self._bouquets_view, self._main_window, g_type, self._TV_TYPES,
|
||||
self._profile, self.append_bouquet)
|
||||
self._s_type, self.append_bouquet)
|
||||
|
||||
# ***************** Profile label *********************#
|
||||
|
||||
def update_profile_label(self):
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
self._header_bar.set_subtitle("{} Enigma2 v.{}".format(get_message("Profile:"), self.get_format_version()))
|
||||
elif self._profile is Profile.NEUTRINO_MP:
|
||||
self._header_bar.set_subtitle("{} Neutrino-MP".format(get_message("Profile:")))
|
||||
label, sep, ip = self._profile_combo_box.get_tooltip_text().partition(":")
|
||||
profile_name = self._profile_combo_box.get_active_text()
|
||||
self._profile_combo_box.set_tooltip_text("{}: {}".format(label, self._settings.host))
|
||||
msg = get_message("Profile:")
|
||||
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
self._header_bar.set_subtitle("{} {} [Enigma2 v.{}]".format(msg, profile_name, self.get_format_version()))
|
||||
elif self._s_type is SettingsType.NEUTRINO_MP:
|
||||
self._header_bar.set_subtitle("{} {} [Neutrino-MP]".format(msg, profile_name))
|
||||
|
||||
def get_format_version(self):
|
||||
return 5 if self._settings.v5_support else 4
|
||||
@@ -2086,8 +2091,14 @@ class Application(Gtk.Application):
|
||||
|
||||
|
||||
def start_app():
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
||||
try:
|
||||
Settings.get_instance()
|
||||
except SettingsException as e:
|
||||
msg = "{} \n{}".format(e, "All setting were reset. Restart the program!")
|
||||
show_dialog(DialogType.INFO, transient=Gtk.Dialog(), text=msg)
|
||||
else:
|
||||
app = Application()
|
||||
app.run(sys.argv)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -9,7 +9,7 @@ from app.commons import run_task
|
||||
from app.eparser import Service
|
||||
from app.eparser.ecommons import Flag, BouquetService, Bouquet, BqType
|
||||
from app.eparser.enigma.bouquets import BqServiceType, to_bouquet_id
|
||||
from app.settings import Profile
|
||||
from app.settings import SettingsType
|
||||
from .uicommons import ViewTarget, BqGenType, Gtk, Gdk, HIDE_ICON, LOCKED_ICON, KeyboardKey, Column
|
||||
from .dialogs import show_dialog, DialogType, get_chooser_dialog, WaitDialog
|
||||
|
||||
@@ -382,7 +382,7 @@ def assign_picon(target, srv_view, fav_view, transient, picons, settings, servic
|
||||
|
||||
if picon_id:
|
||||
if os.path.isfile(response):
|
||||
picons_path = settings.picons_dir_path
|
||||
picons_path = settings.picons_local_path
|
||||
os.makedirs(os.path.dirname(picons_path), exist_ok=True)
|
||||
picon_file = picons_path + picon_id
|
||||
shutil.copy(response, picon_file)
|
||||
@@ -464,8 +464,8 @@ def remove_all_unused_picons(settings, picons, services):
|
||||
|
||||
|
||||
def remove_picons(settings, picon_ids, picons):
|
||||
pions_path = settings.picons_dir_path
|
||||
backup_path = settings.backup_dir_path + "picons/"
|
||||
pions_path = settings.picons_local_path
|
||||
backup_path = settings.backup_local_path + "picons/"
|
||||
os.makedirs(os.path.dirname(backup_path), exist_ok=True)
|
||||
for p_id in picon_ids:
|
||||
picons[p_id] = None
|
||||
@@ -492,7 +492,7 @@ def get_picon_pixbuf(path):
|
||||
|
||||
# ***************** Bouquets *********************#
|
||||
|
||||
def gen_bouquets(view, bq_view, transient, gen_type, tv_types, profile, callback):
|
||||
def gen_bouquets(view, bq_view, transient, gen_type, tv_types, s_type, callback):
|
||||
""" Auto-generate and append list of bouquets """
|
||||
fav_id_index = Column.SRV_FAV_ID
|
||||
index = Column.SRV_TYPE
|
||||
@@ -502,7 +502,7 @@ def gen_bouquets(view, bq_view, transient, gen_type, tv_types, profile, callback
|
||||
index = Column.SRV_POS
|
||||
|
||||
model, paths = view.get_selection().get_selected_rows()
|
||||
bq_type = BqType.BOUQUET.value if profile is Profile.NEUTRINO_MP else BqType.TV.value
|
||||
bq_type = BqType.BOUQUET.value if s_type is SettingsType.NEUTRINO_MP else BqType.TV.value
|
||||
if gen_type in (BqGenType.SAT, BqGenType.PACKAGE, BqGenType.TYPE):
|
||||
if not is_only_one_item_selected(paths, transient):
|
||||
return
|
||||
@@ -511,17 +511,17 @@ def gen_bouquets(view, bq_view, transient, gen_type, tv_types, profile, callback
|
||||
bq_type = BqType.RADIO.value
|
||||
append_bouquets(bq_type, bq_view, callback, fav_id_index, index, model,
|
||||
[service.package if gen_type is BqGenType.PACKAGE else
|
||||
service.pos if gen_type is BqGenType.SAT else service.service_type], profile)
|
||||
service.pos if gen_type is BqGenType.SAT else service.service_type], s_type)
|
||||
else:
|
||||
wait_dialog = WaitDialog(transient)
|
||||
wait_dialog.show()
|
||||
append_bouquets(bq_type, bq_view, callback, fav_id_index, index, model,
|
||||
{row[index] for row in model}, profile, wait_dialog)
|
||||
{row[index] for row in model}, s_type, wait_dialog)
|
||||
|
||||
|
||||
@run_task
|
||||
def append_bouquets(bq_type, bq_view, callback, fav_id_index, index, model, names, profile, wait_dialog=None):
|
||||
bq_index = 0 if profile is Profile.ENIGMA_2 else 1
|
||||
def append_bouquets(bq_type, bq_view, callback, fav_id_index, index, model, names, s_type, wait_dialog=None):
|
||||
bq_index = 0 if s_type is SettingsType.ENIGMA_2 else 1
|
||||
bq_view.expand_row(Gtk.TreePath(bq_index), 0)
|
||||
bqs_model = bq_view.get_model()
|
||||
bouquets_names = get_bouquets_names(bqs_model)
|
||||
@@ -583,14 +583,14 @@ def append_text_to_tview(char, view):
|
||||
view.scroll_to_mark(insert, 0.0, True, 0.0, 1.0)
|
||||
|
||||
|
||||
def get_iptv_url(row, profile):
|
||||
def get_iptv_url(row, s_type):
|
||||
""" Returns url from iptv type row """
|
||||
data = row[Column.FAV_ID].split(":" if profile is Profile.ENIGMA_2 else "::")
|
||||
if profile is Profile.ENIGMA_2:
|
||||
data = row[Column.FAV_ID].split(":" if s_type is SettingsType.ENIGMA_2 else "::")
|
||||
if s_type is SettingsType.ENIGMA_2:
|
||||
data = list(filter(lambda x: "http" in x, data))
|
||||
if data:
|
||||
url = data[0]
|
||||
return urllib.request.unquote(url) if profile is Profile.ENIGMA_2 else url
|
||||
return urllib.request.unquote(url) if s_type is SettingsType.ENIGMA_2 else url
|
||||
|
||||
|
||||
def on_popup_menu(menu, event):
|
||||
|
||||
@@ -26,7 +26,7 @@ THE SOFTWARE.
|
||||
Author: Dmitriy Yefremov
|
||||
|
||||
-->
|
||||
<interface>
|
||||
<interface domain="demon-editor">
|
||||
<requires lib="gtk+" version="3.16"/>
|
||||
<!-- interface-css-provider-path style.css -->
|
||||
<!-- interface-license-type mit -->
|
||||
@@ -961,6 +961,7 @@ Author: Dmitriy Yefremov
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="main_window">
|
||||
<property name="width_request">640</property>
|
||||
<property name="height_request">480</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="window_position">center</property>
|
||||
<property name="icon_name">accessories-text-editor</property>
|
||||
@@ -2798,7 +2799,7 @@ Author: Dmitriy Yefremov
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="status_bar_box">
|
||||
<property name="height_request">30</property>
|
||||
<property name="height_request">35</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="receiver_info_box">
|
||||
@@ -2842,62 +2843,56 @@ Author: Dmitriy Yefremov
|
||||
</packing>
|
||||
</child>
|
||||
<child type="center">
|
||||
<object class="GtkBox" id="ip_status_box">
|
||||
<property name="visible">True</property>
|
||||
<object class="GtkComboBoxText" id="profile_combo_box">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Current IP:</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="ip_status_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-connect</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="ip_status_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin_top">1</property>
|
||||
<property name="margin_bottom">1</property>
|
||||
<property name="active">0</property>
|
||||
<property name="has_frame">False</property>
|
||||
<property name="has_entry">True</property>
|
||||
<items>
|
||||
<item translatable="yes">default</item>
|
||||
</items>
|
||||
<child internal-child="entry">
|
||||
<object class="GtkEntry">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="has_tooltip">True</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="label" translatable="yes">Current IP:</property>
|
||||
<attributes>
|
||||
<attribute name="size" value="8000"/>
|
||||
</attributes>
|
||||
<property name="margin_top">1</property>
|
||||
<property name="margin_bottom">1</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="has_frame">False</property>
|
||||
<property name="max_width_chars">9</property>
|
||||
<property name="text" translatable="yes">default</property>
|
||||
<property name="primary_icon_stock">gtk-connect</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="ip_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">127.0.0.1</property>
|
||||
<attributes>
|
||||
<attribute name="size" value="8000"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="http_status_image">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">No connection to the receiver</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="icon_name">network-offline</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="signal_box">
|
||||
<property name="can_focus">False</property>
|
||||
@@ -2986,21 +2981,6 @@ Author: Dmitriy Yefremov
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="http_status_image">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">No connection to the receiver</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="icon_name">network-offline</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="primary-toolbar"/>
|
||||
</style>
|
||||
|
||||
@@ -9,7 +9,7 @@ from gi.repository import GLib, GdkPixbuf
|
||||
from app.commons import run_idle, run_task
|
||||
from app.connections import upload_data, DownloadType
|
||||
from app.tools.picons import PiconsParser, parse_providers, Provider, convert_to
|
||||
from app.settings import Profile
|
||||
from app.settings import SettingsType
|
||||
from app.tools.satellites import SatellitesParser, SatelliteSource
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN, TV_ICON
|
||||
from .dialogs import show_dialog, DialogType, get_message
|
||||
@@ -86,13 +86,13 @@ class PiconsDialog:
|
||||
self._url_entry.get_style_context().add_provider_for_screen(Gdk.Screen.get_default(), self._style_provider,
|
||||
Gtk.STYLE_PROVIDER_PRIORITY_USER)
|
||||
self._settings = settings
|
||||
self._profile = settings.profile
|
||||
self._s_type = settings.setting_type
|
||||
self._ip_entry.set_text(self._settings.host)
|
||||
self._picons_entry.set_text(self._settings.picons_path)
|
||||
self._picons_path = self._settings.picons_dir_path
|
||||
self._picons_path = self._settings.picons_local_path
|
||||
self._picons_dir_entry.set_text(self._picons_path)
|
||||
|
||||
if not len(self._picon_ids) and self._profile is Profile.ENIGMA_2:
|
||||
if not len(self._picon_ids) and self._s_type is SettingsType.ENIGMA_2:
|
||||
message = get_message("To automatically set the identifiers for picons,\n"
|
||||
"first load the required services list into the main application window.")
|
||||
self.show_info_message(message, Gtk.MessageType.WARNING)
|
||||
@@ -342,7 +342,7 @@ class PiconsDialog:
|
||||
self._expander.set_expanded(True)
|
||||
convert_to(src_path=picons_path,
|
||||
dest_path=save_path,
|
||||
profile=Profile.ENIGMA_2,
|
||||
s_type=SettingsType.ENIGMA_2,
|
||||
callback=self.append_output,
|
||||
done_callback=lambda: self.show_info_message(get_message("Done!"), Gtk.MessageType.INFO))
|
||||
|
||||
@@ -362,10 +362,10 @@ class PiconsDialog:
|
||||
show_dialog(dialog_type, self._dialog, message)
|
||||
|
||||
def get_picons_format(self):
|
||||
picon_format = Profile.ENIGMA_2
|
||||
picon_format = SettingsType.ENIGMA_2
|
||||
|
||||
if self._neutrino_mp_radio_button.get_active():
|
||||
picon_format = Profile.NEUTRINO_MP
|
||||
picon_format = SettingsType.NEUTRINO_MP
|
||||
|
||||
return picon_format
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class SatellitesDialog:
|
||||
_aggr = [None for x in range(9)] # aggregate
|
||||
|
||||
def __init__(self, transient, settings):
|
||||
self._data_path = settings.data_dir_path + "satellites.xml"
|
||||
self._data_path = settings.data_local_path + "satellites.xml"
|
||||
self._settings = settings
|
||||
|
||||
handlers = {"on_open": self.on_open,
|
||||
|
||||
@@ -6,7 +6,7 @@ from app.eparser import Service
|
||||
from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag, Pids, POLARIZATION, \
|
||||
get_key_by_value, get_value_by_name, FEC_DEFAULT, PLS_MODE, SERVICE_TYPE, T_MODULATION, C_MODULATION, TrType, \
|
||||
SystemCable, T_SYSTEM, BANDWIDTH, TRANSMISSION_MODE, GUARD_INTERVAL, HIERARCHY, T_FEC
|
||||
from app.settings import Profile
|
||||
from app.settings import SettingsType
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, HIDE_ICON, TEXT_DOMAIN, CODED_ICON, Column, IS_GNOME_SESSION
|
||||
from .dialogs import show_dialog, DialogType, Action, get_dialogs_string
|
||||
from .main_helper import get_base_model
|
||||
@@ -52,10 +52,10 @@ class ServiceDetailsDialog:
|
||||
|
||||
self._dialog = builder.get_object("service_details_dialog")
|
||||
self._dialog.set_transient_for(transient)
|
||||
self._profile = settings.profile
|
||||
self._s_type = settings.setting_type
|
||||
self._tr_type = None
|
||||
self._satellites_xml_path = settings.data_dir_path + "satellites.xml"
|
||||
self._picons_dir_path = settings.picons_dir_path
|
||||
self._satellites_xml_path = settings.data_local_path + "satellites.xml"
|
||||
self._picons_dir_path = settings.picons_local_path
|
||||
self._services_view = srv_view
|
||||
self._fav_view = fav_view
|
||||
self._action = action
|
||||
@@ -197,7 +197,7 @@ class ServiceDetailsDialog:
|
||||
self._package_entry.set_text(srv.package)
|
||||
self._sid_entry.set_text(str(int(srv.ssid, 16)))
|
||||
# Transponder
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
self._tr_type = TrType(srv.transponder_type)
|
||||
self._freq_entry.set_text(srv.freq)
|
||||
self._rate_entry.set_text(srv.rate)
|
||||
@@ -211,10 +211,10 @@ class ServiceDetailsDialog:
|
||||
else:
|
||||
self.set_sat_positions(srv.pos)
|
||||
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
self.init_enigma2_service_data(srv)
|
||||
self.init_enigma2_transponder_data(srv)
|
||||
elif self._profile is Profile.NEUTRINO_MP:
|
||||
elif self._s_type is SettingsType.NEUTRINO_MP:
|
||||
self.init_neutrino_data(srv)
|
||||
self.init_neutrino_ui_elements()
|
||||
|
||||
@@ -484,9 +484,9 @@ class ServiceDetailsDialog:
|
||||
transponder=transponder)
|
||||
|
||||
def get_flags(self):
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
return self.get_enigma2_flags()
|
||||
elif self._profile is Profile.NEUTRINO_MP:
|
||||
elif self._s_type is SettingsType.NEUTRINO_MP:
|
||||
return self._old_service.flags_cas
|
||||
|
||||
def get_enigma2_flags(self):
|
||||
@@ -532,12 +532,12 @@ class ServiceDetailsDialog:
|
||||
net_id, tr_id = int(self._network_id_entry.get_text()), int(self._transponder_id_entry.get_text())
|
||||
service_type = self._srv_type_entry.get_text()
|
||||
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
namespace = int(self._namespace_entry.get_text())
|
||||
data_id = self._ENIGMA2_DATA_ID.format(ssid, namespace, tr_id, net_id, service_type, 0)
|
||||
fav_id = self._ENIGMA2_FAV_ID.format(ssid, tr_id, net_id, namespace)
|
||||
return fav_id, data_id
|
||||
elif self._profile is Profile.NEUTRINO_MP:
|
||||
elif self._s_type is SettingsType.NEUTRINO_MP:
|
||||
fav_id = self._NEUTRINO_FAV_ID.format(tr_id, net_id, ssid)
|
||||
return fav_id, self._old_service.data_id
|
||||
|
||||
@@ -548,7 +548,7 @@ class ServiceDetailsDialog:
|
||||
fec = self._fec_combo_box.get_active_id()
|
||||
system = self._sys_combo_box.get_active_id()
|
||||
|
||||
if self._tr_type is TrType.Satellite or self._profile is Profile.NEUTRINO_MP:
|
||||
if self._tr_type is TrType.Satellite or self._s_type is SettingsType.NEUTRINO_MP:
|
||||
freq = self._freq_entry.get_text()
|
||||
rate = self._rate_entry.get_text()
|
||||
pol = self._pol_combo_box.get_active_id()
|
||||
@@ -571,7 +571,7 @@ class ServiceDetailsDialog:
|
||||
inv = get_value_by_name(Inversion, self._invertion_combo_box.get_active_id())
|
||||
srv_sys = "0" # !!!
|
||||
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
dvb_s_tr = self._ENIGMA2_TRANSPONDER_DATA.format("s", freq, rate, pol, fec, sat_pos, inv, srv_sys)
|
||||
if sys == "DVB-S":
|
||||
return dvb_s_tr
|
||||
@@ -585,7 +585,7 @@ class ServiceDetailsDialog:
|
||||
st_id = self._stream_id_entry.get_text()
|
||||
pls = ":{}:{}:{}".format(st_id, pls_code, pls_mode) if pls_mode and pls_code and st_id else ""
|
||||
return "{}:{}:{}:{}:{}{}".format(dvb_s_tr, flag, mod, roll_off, pilot, pls)
|
||||
elif self._profile is Profile.NEUTRINO_MP:
|
||||
elif self._s_type is SettingsType.NEUTRINO_MP:
|
||||
on_id, tr_id = int(self._network_id_entry.get_text()), int(self._transponder_id_entry.get_text())
|
||||
mod = self.get_value_from_combobox_id(self._mod_combo_box, MODULATION) if sys == "DVB-S2" else None
|
||||
srv_sys = None
|
||||
@@ -682,7 +682,7 @@ class ServiceDetailsDialog:
|
||||
return True
|
||||
|
||||
def update_reference(self, entry, event=None):
|
||||
if not self.is_data_correct() or (event is None and self._profile is Profile.NEUTRINO_MP):
|
||||
if not self.is_data_correct() or (event is None and self._s_type is SettingsType.NEUTRINO_MP):
|
||||
return
|
||||
self.update_reference_entry()
|
||||
|
||||
@@ -691,7 +691,7 @@ class ServiceDetailsDialog:
|
||||
ssid = int(self._sid_entry.get_text())
|
||||
tid = int(self._transponder_id_entry.get_text())
|
||||
nid = int(self._network_id_entry.get_text())
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
on_id = int(self._namespace_entry.get_text())
|
||||
ref = "1:0:{:X}:{:X}:{:X}:{:X}:{:X}:0:0:0".format(srv_type, ssid, tid, nid, on_id)
|
||||
self._reference_entry.set_text(ref)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,8 @@ from enum import Enum
|
||||
|
||||
from app.commons import run_task, run_idle
|
||||
from app.connections import test_telnet, test_ftp, TestException, test_http
|
||||
from app.settings import Profile
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN, FavClickMode
|
||||
from app.settings import SettingsType
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, FavClickMode, DEFAULT_ICON
|
||||
from .main_helper import update_entry_data
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ class SettingsDialog:
|
||||
|
||||
def __init__(self, transient, settings):
|
||||
handlers = {"on_field_icon_press": self.on_field_icon_press,
|
||||
"on_profile_changed": self.on_profile_changed,
|
||||
"on_settings_type_changed": self.on_settings_type_changed,
|
||||
"on_reset": self.on_reset,
|
||||
"apply_settings": self.apply_settings,
|
||||
"on_connection_test": self.on_connection_test,
|
||||
@@ -29,10 +29,16 @@ class SettingsDialog:
|
||||
"on_set_color_switch_state": self.on_set_color_switch_state,
|
||||
"on_http_mode_switch_state": self.on_http_mode_switch_state,
|
||||
"on_yt_dl_switch_state": self.on_yt_dl_switch_state,
|
||||
"on_send_to_switch_state": self.on_send_to_switch_state}
|
||||
"on_send_to_switch_state": self.on_send_to_switch_state,
|
||||
"on_profile_add": self.on_profile_add,
|
||||
"on_profile_edit": self.on_profile_edit,
|
||||
"on_profile_remove": self.on_profile_remove,
|
||||
"on_profile_deleted": self.on_profile_deleted,
|
||||
"on_profile_inserted": self.on_profile_inserted,
|
||||
"on_profile_edited": self.on_profile_edited,
|
||||
"on_profile_set_default": self.on_profile_set_default}
|
||||
|
||||
builder = Gtk.Builder()
|
||||
builder.set_translation_domain(TEXT_DOMAIN)
|
||||
builder.add_from_file(UI_RESOURCES_PATH + "settings_dialog.glade")
|
||||
builder.connect_signals(handlers)
|
||||
|
||||
@@ -89,23 +95,38 @@ class SettingsDialog:
|
||||
self._click_mode_zap_button.bind_property("sensitive", self._enable_send_to_switch, "sensitive")
|
||||
self._enable_send_to_switch.bind_property("sensitive", builder.get_object("enable_send_to_label"), "sensitive")
|
||||
self._extra_support_grid.bind_property("sensitive", builder.get_object("v5_support_grid"), "sensitive")
|
||||
# Profiles
|
||||
self._profile_view = builder.get_object("profile_tree_view")
|
||||
self._profile_remove_button = builder.get_object("profile_remove_button")
|
||||
self._profile_view.get_model().append(("default", DEFAULT_ICON))
|
||||
# Settings
|
||||
self._settings = settings
|
||||
self._active_profile = settings.profile
|
||||
self._profiles = settings.profiles
|
||||
self._s_type = settings.setting_type
|
||||
self.set_settings()
|
||||
self.init_ui_elements(self._active_profile)
|
||||
self.init_ui_elements(self._s_type)
|
||||
|
||||
def init_ui_elements(self, profile):
|
||||
is_enigma_profile = profile is Profile.ENIGMA_2
|
||||
self._neutrino_radio_button.set_active(profile is Profile.NEUTRINO_MP)
|
||||
@run_idle
|
||||
def init_ui_elements(self, s_type):
|
||||
is_enigma_profile = s_type is SettingsType.ENIGMA_2
|
||||
self._neutrino_radio_button.set_active(s_type is SettingsType.NEUTRINO_MP)
|
||||
self.update_header_bar()
|
||||
self._settings_stack.get_child_by_name(Property.HTTP.value).set_visible(is_enigma_profile)
|
||||
self._program_frame.set_sensitive(is_enigma_profile)
|
||||
self._extra_support_grid.set_sensitive(is_enigma_profile)
|
||||
http_active = self._support_http_api_switch.get_active()
|
||||
self._click_mode_zap_button.set_sensitive(is_enigma_profile and http_active)
|
||||
self._profile_remove_button.set_sensitive(len(self._profile_view.get_model()) > 1)
|
||||
self.on_info_bar_close() if is_enigma_profile else self.show_info_message(
|
||||
"The Neutrino has only experimental support. Not all features are supported!", Gtk.MessageType.WARNING)
|
||||
|
||||
def update_header_bar(self):
|
||||
label, sep, st = self._header_bar.get_subtitle().partition(":")
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
self._header_bar.set_subtitle("{}: {}".format(label, self._enigma_radio_button.get_label()))
|
||||
elif self._s_type is SettingsType.NEUTRINO_MP:
|
||||
self._header_bar.set_subtitle("{}: {}".format(label, self._neutrino_radio_button.get_label()))
|
||||
|
||||
def show(self):
|
||||
response = self._dialog.run()
|
||||
if response == Gtk.ResponseType.OK:
|
||||
@@ -117,10 +138,10 @@ class SettingsDialog:
|
||||
def on_field_icon_press(self, entry, icon, event_button):
|
||||
update_entry_data(entry, self._dialog, self._settings)
|
||||
|
||||
def on_profile_changed(self, item):
|
||||
profile = Profile.ENIGMA_2 if self._enigma_radio_button.get_active() else Profile.NEUTRINO_MP
|
||||
self._active_profile = profile
|
||||
self._settings.profile = profile
|
||||
def on_settings_type_changed(self, item):
|
||||
profile = SettingsType.ENIGMA_2 if self._enigma_radio_button.get_active() else SettingsType.NEUTRINO_MP
|
||||
self._s_type = profile
|
||||
self._settings.setting_type = profile
|
||||
self.set_settings()
|
||||
self.init_ui_elements(profile)
|
||||
|
||||
@@ -144,14 +165,14 @@ class SettingsDialog:
|
||||
self._user_bouquet_field.set_text(self._settings.user_bouquet_path)
|
||||
self._satellites_xml_field.set_text(self._settings.satellites_xml_path)
|
||||
self._picons_field.set_text(self._settings.picons_path)
|
||||
self._data_dir_field.set_text(self._settings.data_dir_path)
|
||||
self._picons_dir_field.set_text(self._settings.picons_dir_path)
|
||||
self._backup_dir_field.set_text(self._settings.backup_dir_path)
|
||||
self._data_dir_field.set_text(self._settings.data_local_path)
|
||||
self._picons_dir_field.set_text(self._settings.picons_local_path)
|
||||
self._backup_dir_field.set_text(self._settings.backup_local_path)
|
||||
self._before_save_switch.set_active(self._settings.backup_before_save)
|
||||
self._before_downloading_switch.set_active(self._settings.backup_before_downloading)
|
||||
self.set_fav_click_mode(self._settings.fav_click_mode)
|
||||
|
||||
if self._active_profile is Profile.ENIGMA_2:
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
self._support_ver5_switch.set_active(self._settings.v5_support)
|
||||
self._support_http_api_switch.set_active(self._settings.http_api_support)
|
||||
self._enable_y_dl_switch.set_active(self._settings.enable_yt_dl)
|
||||
@@ -165,8 +186,8 @@ class SettingsDialog:
|
||||
self._extra_color_button.set_rgba(extra_rgb)
|
||||
|
||||
def apply_settings(self, item=None):
|
||||
self._active_profile = Profile.ENIGMA_2 if self._enigma_radio_button.get_active() else Profile.NEUTRINO_MP
|
||||
self._settings.profile = self._active_profile
|
||||
self._s_type = SettingsType.ENIGMA_2 if self._enigma_radio_button.get_active() else SettingsType.NEUTRINO_MP
|
||||
self._settings.setting_type = self._s_type
|
||||
self._settings.host = self._host_field.get_text()
|
||||
self._settings.port = self._port_field.get_text()
|
||||
self._settings.user = self._login_field.get_text()
|
||||
@@ -182,14 +203,14 @@ class SettingsDialog:
|
||||
self._settings.user_bouquet_path = self._user_bouquet_field.get_text()
|
||||
self._settings.satellites_xml_path = self._satellites_xml_field.get_text()
|
||||
self._settings.picons_path = self._picons_field.get_text()
|
||||
self._settings.data_dir_path = self._data_dir_field.get_text()
|
||||
self._settings.picons_dir_path = self._picons_dir_field.get_text()
|
||||
self._settings.backup_dir_path = self._backup_dir_field.get_text()
|
||||
self._settings.data_local_path = self._data_dir_field.get_text()
|
||||
self._settings.picons_local_path = self._picons_dir_field.get_text()
|
||||
self._settings.backup_local_path = self._backup_dir_field.get_text()
|
||||
self._settings.backup_before_save = self._before_save_switch.get_active()
|
||||
self._settings.backup_before_downloading = self._before_downloading_switch.get_active()
|
||||
self._settings.fav_click_mode = self.get_fav_click_mode()
|
||||
|
||||
if self._active_profile is Profile.ENIGMA_2:
|
||||
if self._s_type is SettingsType.ENIGMA_2:
|
||||
self._settings.use_colors = self._set_color_switch.get_active()
|
||||
self._settings.new_color = self._new_color_button.get_rgba().to_string()
|
||||
self._settings.extra_color = self._extra_color_button.get_rgba().to_string()
|
||||
@@ -272,6 +293,42 @@ class SettingsDialog:
|
||||
def on_send_to_switch_state(self, switch, state):
|
||||
self.show_info_message("Not implemented yet!", Gtk.MessageType.WARNING)
|
||||
|
||||
def on_profile_add(self, item):
|
||||
model = self._profile_view.get_model()
|
||||
count = 0
|
||||
name = "profile"
|
||||
while name in self._profiles:
|
||||
count += 1
|
||||
name = "profile{}".format(count)
|
||||
self._profiles[name] = {"host": self._host_field.get_text()}
|
||||
itr = model.append((name, None))
|
||||
|
||||
def on_profile_edit(self, item):
|
||||
self.show_info_message("Not implemented yet!", Gtk.MessageType.WARNING)
|
||||
|
||||
def on_profile_remove(self, item):
|
||||
model, paths = self._profile_view.get_selection().get_selected_rows()
|
||||
if paths:
|
||||
row = model[paths]
|
||||
self._profiles.pop(row[0], None)
|
||||
del model[paths]
|
||||
|
||||
def on_profile_deleted(self, model, paths):
|
||||
self._profile_remove_button.set_sensitive(len(model) > 1)
|
||||
|
||||
def on_profile_edited(self, render, path, new_text):
|
||||
p_name = render.get_property("text")
|
||||
p_data = self._profiles.pop(p_name, None)
|
||||
row = self._profile_view.get_model()[path]
|
||||
row[0] = new_text
|
||||
self._profiles[new_text] = p_data
|
||||
|
||||
def on_profile_set_default(self, item):
|
||||
self.show_info_message("Not implemented yet!", Gtk.MessageType.WARNING)
|
||||
|
||||
def on_profile_inserted(self, model, path, itr):
|
||||
self._profile_remove_button.set_sensitive(len(model) > 1)
|
||||
|
||||
@run_idle
|
||||
def set_fav_click_mode(self, mode):
|
||||
mode = FavClickMode(mode)
|
||||
|
||||
@@ -28,6 +28,7 @@ HIDE_ICON = theme.load_icon("go-jump", 16, 0) if theme.lookup_icon("go-jump", 16
|
||||
TV_ICON = theme.load_icon("tv-symbolic", 16, 0) if theme.lookup_icon("tv-symbolic", 16, 0) else _IMAGE_MISSING
|
||||
IPTV_ICON = theme.load_icon("emblem-shared", 16, 0) if theme.lookup_icon("emblem-shared", 16, 0) else None
|
||||
EPG_ICON = theme.load_icon("gtk-index", 16, 0) if theme.lookup_icon("gtk-index", 16, 0) else None
|
||||
DEFAULT_ICON = theme.load_icon("emblem-default", 16, 0) if theme.lookup_icon("emblem-default", 16, 0) else None
|
||||
|
||||
|
||||
class KeyboardKey(Enum):
|
||||
|
||||
Reference in New Issue
Block a user