paths settings rework

This commit is contained in:
DYefremov
2021-08-30 15:04:15 +03:00
parent b584126bff
commit 7da3c0fd94
16 changed files with 450 additions and 198 deletions

View File

@@ -328,7 +328,7 @@ def download_data(*, settings, download_type=DownloadType.ALL, callback=log, fil
with UtfFTP(host=settings.host, user=settings.user, passwd=settings.password) as ftp:
ftp.encoding = "utf-8"
callback("FTP OK.\n")
save_path = settings.data_local_path
save_path = settings.profile_data_path
os.makedirs(os.path.dirname(save_path), exist_ok=True)
# bouquets
if download_type is DownloadType.ALL or download_type is DownloadType.BOUQUETS:
@@ -342,7 +342,7 @@ def download_data(*, settings, download_type=DownloadType.ALL, callback=log, fil
ftp.download_xml(save_path, settings.satellites_xml_path, WEB_TV_XML_FILE, callback)
if download_type is DownloadType.PICONS:
picons_path = settings.picons_local_path
picons_path = settings.profile_picons_path
os.makedirs(os.path.dirname(picons_path), exist_ok=True)
ftp.download_picons(settings.picons_path, picons_path, callback, files_filter)
# epg.dat
@@ -362,7 +362,7 @@ def download_data(*, settings, download_type=DownloadType.ALL, callback=log, fil
def upload_data(*, settings, download_type=DownloadType.ALL, remove_unused=False,
callback=log, done_callback=None, use_http=False, files_filter=None):
s_type = settings.setting_type
data_path = settings.data_local_path
data_path = settings.profile_data_path
host = settings.host
base_url = "http{}://{}:{}".format("s" if settings.http_use_ssl else "", host, settings.http_port)
url = "{}/web/".format(base_url)
@@ -428,7 +428,7 @@ def upload_data(*, settings, download_type=DownloadType.ALL, remove_unused=False
ftp.upload_files(data_path, DATA_FILES_LIST, callback)
if download_type is DownloadType.PICONS:
ftp.upload_picons(settings.picons_local_path, settings.picons_path, callback, files_filter)
ftp.upload_picons(settings.profile_picons_path, settings.picons_path, callback, files_filter)
if tn and not use_http:
# resume enigma or restart neutrino

View File

@@ -1,3 +1,31 @@
# -*- coding: utf-8 -*-
#
# The MIT License (MIT)
#
# Copyright (c) 2018-2021 Dmitriy Yefremov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Author: Dmitriy Yefremov
#
import copy
import json
import locale
@@ -13,7 +41,7 @@ SEP = os.sep
HOME_PATH = str(Path.home())
CONFIG_PATH = HOME_PATH + "{}.config{}demon-editor{}".format(SEP, SEP, SEP)
CONFIG_FILE = CONFIG_PATH + "config.json"
DATA_PATH = HOME_PATH + "{}DemonEditor{}data{}".format(SEP, SEP, SEP)
DATA_PATH = HOME_PATH + "{}DemonEditor{}".format(SEP, SEP)
GTK_PATH = os.environ.get("GTK_PATH", None)
IS_DARWIN = sys.platform == "darwin"
@@ -23,6 +51,31 @@ IS_LINUX = sys.platform == "linux"
class Defaults(Enum):
""" Default program settings """
USER = "root"
PASSWORD = ""
HOST = "127.0.0.1"
FTP_PORT = "21"
HTTP_PORT = "80"
TELNET_PORT = "23"
HTTP_USE_SSL = False
# Enigma2.
BOX_SERVICES_PATH = "/etc/enigma2/"
BOX_SATELLITE_PATH = "/etc/tuxbox/"
BOX_PICON_PATH = "/usr/share/enigma2/picon/"
BOX_PICON_PATHS = ("/usr/share/enigma2/picon/",
"/media/hdd/picon/",
"/media/usb/picon/",
"/media/mmc/picon/",
"/media/cf/picon/")
# Neutrino.
NEUTRINO_BOX_SERVICES_PATH = "/var/tuxbox/config/zapit/"
NEUTRINO_BOX_SATELLITE_PATH = "/var/tuxbox/config/"
NEUTRINO_BOX_PICON_PATH = "/usr/share/tuxbox/neutrino/icons/logo/"
NEUTRINO_BOX_PICON_PATHS = ("/usr/share/tuxbox/neutrino/icons/logo/",)
# Paths.
BACKUP_PATH = "{}backup{}".format(DATA_PATH, SEP)
PICON_PATH = "{}picons{}".format(DATA_PATH, SEP)
DEFAULT_PROFILE = "default"
BACKUP_BEFORE_DOWNLOADING = True
BACKUP_BEFORE_SAVE = True
@@ -43,64 +96,6 @@ class Defaults(Enum):
RECORDS_PATH = DATA_PATH + "records{}".format(SEP)
ACTIVATE_TRANSCODING = False
ACTIVE_TRANSCODING_PRESET = "720p TV{}device".format(SEP)
ENIGMA_2_PICONS_PATHS = ("/usr/share/enigma2/picon/",
"/media/hdd/picon/",
"/media/usb/picon/",
"/media/mmc/picon/",
"/media/cf/picon/")
NEUTRINO_PICONS_PATHS = ("/usr/share/tuxbox/neutrino/icons/logo/",)
def get_settings():
if not os.path.isfile(CONFIG_FILE) or os.stat(CONFIG_FILE).st_size == 0:
write_settings(get_default_settings())
with open(CONFIG_FILE, "r", encoding="utf-8") as config_file:
return json.load(config_file)
def get_default_settings(profile_name="default"):
def_settings = SettingsType.ENIGMA_2.get_default_settings()
set_local_paths(def_settings, profile_name)
return {
"version": 1,
"default_profile": Defaults.DEFAULT_PROFILE.value,
"profiles": {profile_name: def_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,
"profile_folder_is_default": Defaults.PROFILE_FOLDER_DEFAULT.value,
"records_path": Defaults.RECORDS_PATH.value
}
def get_default_transcoding_presets():
return {"720p TV/device": {"vcodec": "h264", "vb": "1500", "width": "1280", "height": "720", "acodec": "mp3",
"ab": "192", "channels": "2", "samplerate": "44100", "scodec": "none"},
"1080p TV/device": {"vcodec": "h264", "vb": "3500", "width": "1920", "height": "1080", "acodec": "mp3",
"ab": "192", "channels": "2", "samplerate": "44100", "scodec": "none"}}
def write_settings(config):
os.makedirs(os.path.dirname(CONFIG_PATH), exist_ok=True)
with open(CONFIG_FILE, "w", encoding="utf-8") as config_file:
json.dump(config, config_file, indent=" ")
def set_local_paths(settings, profile_name, data_path=DATA_PATH, use_profile_folder=False):
settings["data_local_path"] = "{}{}{}".format(data_path, profile_name, SEP)
if use_profile_folder:
settings["picons_local_path"] = "{}{}{}{}{}".format(data_path, profile_name, SEP, "picons", SEP)
settings["backup_local_path"] = "{}{}{}{}{}".format(data_path, profile_name, SEP, "backup", SEP)
else:
settings["picons_local_path"] = "{}{}{}{}{}".format(data_path, "picons", SEP, profile_name, SEP)
settings["backup_local_path"] = "{}{}{}{}{}".format(data_path, "backup", SEP, profile_name, SEP)
class SettingsType(IntEnum):
@@ -109,29 +104,35 @@ class SettingsType(IntEnum):
NEUTRINO_MP = 1
def get_default_settings(self):
""" Returns default settings for current type """
""" Returns default settings for current type. """
if self is self.ENIGMA_2:
srv_path = Defaults.BOX_SERVICES_PATH.value
sat_path = Defaults.BOX_SATELLITE_PATH.value
picons_path = Defaults.BOX_PICON_PATH.value
http_timeout = 5
telnet_timeout = 5
else:
srv_path = Defaults.NEUTRINO_BOX_SERVICES_PATH.value
sat_path = Defaults.NEUTRINO_BOX_SATELLITE_PATH.value
picons_path = Defaults.NEUTRINO_BOX_PICON_PATH.value
http_timeout = 2
telnet_timeout = 1
return {"setting_type": self.value,
"host": "127.0.0.1", "port": "21", "timeout": 5,
"user": "root", "password": "root",
"http_port": "80", "http_timeout": 5, "http_use_ssl": False,
"telnet_port": "23", "telnet_timeout": 5,
"services_path": "/etc/enigma2/", "user_bouquet_path": "/etc/enigma2/",
"satellites_xml_path": "/etc/tuxbox/", "data_local_path": "{}enigma2{}".format(DATA_PATH, SEP),
"picons_path": "/usr/share/enigma2/picon/",
"picons_local_path": "{}enigma2{}picons{}".format(DATA_PATH, SEP, SEP),
"backup_local_path": "{}enigma2{}backup{}".format(DATA_PATH, SEP, SEP)}
elif self is SettingsType.NEUTRINO_MP:
return {"setting_type": self,
"host": "127.0.0.1", "port": "21", "timeout": 5,
"user": "root", "password": "root",
"http_port": "80", "http_timeout": 2, "http_use_ssl": False,
"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/"}
"host": Defaults.HOST.value,
"port": Defaults.FTP_PORT.value,
"timeout": 5,
"user": Defaults.USER.value,
"password": Defaults.PASSWORD.value,
"http_port": Defaults.HTTP_PORT.value,
"http_timeout": http_timeout,
"http_use_ssl": Defaults.HTTP_USE_SSL.value,
"telnet_port": Defaults.TELNET_PORT.value,
"telnet_timeout": telnet_timeout,
"services_path": srv_path,
"user_bouquet_path": srv_path,
"satellites_xml_path": sat_path,
"picons_path": picons_path}
class SettingsException(Exception):
@@ -151,11 +152,11 @@ class PlayStreamsMode(IntEnum):
class Settings:
__INSTANCE = None
__VERSION = 1
__VERSION = 2
def __init__(self, ext_settings=None):
try:
settings = ext_settings or get_settings()
settings = ext_settings or self.get_settings()
except PermissionError as e:
raise SettingsReadException(e)
@@ -186,22 +187,18 @@ class Settings:
return cls.__INSTANCE
def save(self):
write_settings(self._settings)
self.write_settings(self._settings)
def reset(self, force_write=False):
for k, v in self.setting_type.get_default_settings().items():
self._cp_settings[k] = v
def_path = DATA_PATH
def_path += "enigma2/" if self.setting_type is SettingsType.ENIGMA_2 else "neutrino/"
set_local_paths(self._cp_settings, self._current_profile, def_path, self.profile_folder_is_default)
if force_write:
self.save()
@staticmethod
def reset_to_default():
write_settings(get_default_settings())
Settings.write_settings(Settings.get_default_settings())
def get_default(self, p_name):
""" Returns default value for current settings type """
@@ -242,6 +239,10 @@ class Settings:
def default_profile(self, value):
self._settings["default_profile"] = value
@property
def current_profile_settings(self):
return self._cp_settings
@property
def profiles(self):
return self._profiles
@@ -368,8 +369,8 @@ class Settings:
@property
def picons_paths(self):
if self.setting_type is SettingsType.NEUTRINO_MP:
return Defaults.NEUTRINO_PICONS_PATHS.value
return Defaults.ENIGMA_2_PICONS_PATHS.value
return Defaults.NEUTRINO_BOX_PICON_PATHS.value
return Defaults.BOX_PICON_PATHS.value
# ***** Local paths ***** #
@@ -382,28 +383,56 @@ class Settings:
self._settings["profile_folder_is_default"] = value
@property
def data_local_path(self):
return self._cp_settings.get("data_local_path", self.get_default("data_local_path"))
def default_data_path(self):
return self._settings.get("default_data_path", DATA_PATH)
@data_local_path.setter
def data_local_path(self, value):
self._cp_settings["data_local_path"] = value
@default_data_path.setter
def default_data_path(self, value):
self._settings["default_data_path"] = value
@property
def picons_local_path(self):
return self._cp_settings.get("picons_local_path", self.get_default("picons_local_path"))
def default_backup_path(self):
return self._settings.get("default_backup_path", Defaults.BACKUP_PATH.value)
@picons_local_path.setter
def picons_local_path(self, value):
self._cp_settings["picons_local_path"] = value
@default_backup_path.setter
def default_backup_path(self, value):
self._settings["default_backup_path"] = value
@property
def backup_local_path(self):
return self._cp_settings.get("backup_local_path", self.get_default("backup_local_path"))
def default_picon_path(self):
return self._settings.get("default_picon_path", Defaults.PICON_PATH.value)
@backup_local_path.setter
def backup_local_path(self, value):
self._cp_settings["backup_local_path"] = value
@default_picon_path.setter
def default_picon_path(self, value):
self._settings["default_picon_path"] = value
@property
def profile_data_path(self):
return "{}data{}{}{}".format(self.default_data_path, SEP, self._current_profile, SEP)
@profile_data_path.setter
def profile_data_path(self, value):
self._cp_settings["profile_data_path"] = value
@property
def profile_picons_path(self):
if self.profile_folder_is_default:
return "{}picons{}".format(self.profile_data_path, SEP)
return "{}{}{}".format(self.default_picon_path, self._current_profile, SEP)
@profile_picons_path.setter
def profile_picons_path(self, value):
self._cp_settings["profile_picons_path"] = value
@property
def profile_backup_path(self):
if self.profile_folder_is_default:
return "{}backup{}".format(self.profile_data_path, SEP)
return "{}{}{}".format(self.default_backup_path, self._current_profile, SEP)
@profile_backup_path.setter
def profile_backup_path(self, value):
self._cp_settings["profile_backup_path"] = value
@property
def records_path(self):
@@ -433,7 +462,7 @@ class Settings:
@property
def transcoding_presets(self):
return self._settings.get("transcoding_presets", get_default_transcoding_presets())
return self._settings.get("transcoding_presets", self.get_default_transcoding_presets())
@transcoding_presets.setter
def transcoding_presets(self, value):
@@ -667,7 +696,7 @@ class Settings:
@property
@lru_cache(1)
def themes_path(self):
return "{}/.themes/".format(HOME_PATH)
return "{}{}.themes{}".format(HOME_PATH, SEP, SEP)
@property
def icon_theme(self):
@@ -680,7 +709,7 @@ class Settings:
@property
@lru_cache(1)
def icon_themes_path(self):
return "{}/.icons/".format(HOME_PATH)
return "{}{}.icons{}".format(HOME_PATH, SEP, SEP)
@property
def is_darwin(self):
@@ -725,6 +754,49 @@ class Settings:
def is_enable_experimental(self, value):
self._settings["enable_experimental"] = value
# **************** Get-Set settings **************** #
@staticmethod
def get_settings():
if not os.path.isfile(CONFIG_FILE) or os.stat(CONFIG_FILE).st_size == 0:
Settings.write_settings(Settings.get_default_settings())
with open(CONFIG_FILE, "r", encoding="utf-8") as config_file:
return json.load(config_file)
@staticmethod
def get_default_settings(profile_name="default"):
def_settings = SettingsType.ENIGMA_2.get_default_settings()
return {
"version": Settings.__VERSION,
"default_profile": Defaults.DEFAULT_PROFILE.value,
"profiles": {profile_name: def_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,
"profile_folder_is_default": Defaults.PROFILE_FOLDER_DEFAULT.value,
"records_path": Defaults.RECORDS_PATH.value
}
@staticmethod
def get_default_transcoding_presets():
return {"720p TV/device": {"vcodec": "h264", "vb": "1500", "width": "1280", "height": "720", "acodec": "mp3",
"ab": "192", "channels": "2", "samplerate": "44100", "scodec": "none"},
"1080p TV/device": {"vcodec": "h264", "vb": "3500", "width": "1920", "height": "1080", "acodec": "mp3",
"ab": "192", "channels": "2", "samplerate": "44100", "scodec": "none"}}
@staticmethod
def write_settings(config):
os.makedirs(os.path.dirname(CONFIG_PATH), exist_ok=True)
with open(CONFIG_FILE, "w", encoding="utf-8") as config_file:
json.dump(config, config_file, indent=" ")
if __name__ == "__main__":
pass

View File

@@ -1,3 +1,31 @@
# -*- coding: utf-8 -*-
#
# The MIT License (MIT)
#
# Copyright (c) 2018-2021 Dmitriy Yefremov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Author: Dmitriy Yefremov
#
""" Module for working with YouTube service """
import gzip
import json
@@ -12,6 +40,7 @@ from urllib.parse import unquote
from urllib.request import Request, urlopen, urlretrieve
from app.commons import log
from app.settings import SEP
from app.ui.uicommons import show_notification
_YT_PATTERN = re.compile(r"https://www.youtube.com/.+(?:v=)([\w-]{11}).*")
@@ -230,7 +259,7 @@ class YouTubeDL:
"cookiefile": "cookies.txt"} # File name where cookies should be read from and dumped to.
def __init__(self, settings, callback):
self._path = settings.default_data_path + "tools/"
self._path = "{}tools{}".format(settings.default_data_path, SEP)
self._update = settings.enable_yt_dl_update
self._supported = {"22", "18"}
self._dl = None
@@ -247,7 +276,7 @@ class YouTubeDL:
return cls._DL_INSTANCE
def init(self):
if not os.path.isfile(self._path + "youtube_dl/version.py"):
if not os.path.isfile("{}youtube_dl{}version.py".format(self._path, SEP)):
self.get_latest_release()
if self._path not in sys.path:

View File

@@ -1,3 +1,31 @@
# -*- coding: utf-8 -*-
#
# The MIT License (MIT)
#
# Copyright (c) 2018-2021 Dmitriy Yefremov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Author: Dmitriy Yefremov
#
import os
import shutil
import tempfile
@@ -7,7 +35,7 @@ from datetime import datetime
from enum import Enum
from app.commons import run_idle
from app.settings import SettingsType
from app.settings import SettingsType, SEP
from app.ui.dialogs import show_dialog, DialogType, get_builder
from app.ui.main_helper import append_text_to_tview
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, KeyboardKey, MOD_MASK
@@ -34,8 +62,8 @@ class BackupDialog:
self._settings = settings
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._data_path = self._settings.profile_data_path
self._backup_path = self._settings.profile_backup_path or "{}backup{}".format(self._data_path, os.sep)
self._open_data_callback = callback
self._dialog_window = builder.get_object("dialog_window")
self._dialog_window.set_transient_for(transient)
@@ -149,7 +177,7 @@ class BackupDialog:
clear_data_path(self._data_path)
shutil.unpack_archive(full_file_name, self._data_path)
elif restore_type is RestoreType.BOUQUETS:
tmp_dir = tempfile.gettempdir() + "/" + file_name
tmp_dir = tempfile.gettempdir() + SEP + file_name
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)):
@@ -188,7 +216,7 @@ def backup_data(path, backup_path, move=True):
Returns full path to the compressed file.
"""
backup_path = "{}{}/".format(backup_path, datetime.now().strftime("%Y-%m-%d_%H-%M-%S"))
backup_path = "{}{}{}".format(backup_path, datetime.now().strftime("%Y-%m-%d_%H-%M-%S"), SEP)
os.makedirs(os.path.dirname(backup_path), exist_ok=True)
os.makedirs(os.path.dirname(path), exist_ok=True)
# backup files in data dir(skipping dirs and satellites.xml)

View File

@@ -141,7 +141,7 @@ def get_file_chooser_dialog(transient, text, settings, action_type, file_filter,
if file_filter is not None:
dialog.add_filter(file_filter)
dialog.set_current_folder(settings.data_local_path)
dialog.set_current_folder(settings.profile_data_path)
response = dialog.run()
if response == Gtk.ResponseType.ACCEPT:

View File

@@ -1,3 +1,31 @@
# -*- coding: utf-8 -*-
#
# The MIT License (MIT)
#
# Copyright (c) 2018-2021 Dmitriy Yefremov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Author: Dmitriy Yefremov
#
import os
from gi.repository import GLib
@@ -58,7 +86,7 @@ class DownloadDialog:
def init_ui_settings(self):
self._host_entry.set_text(self._settings.host)
self._data_path_entry.set_text(self._settings.data_local_path)
self._data_path_entry.set_text(self._settings.profile_data_path)
is_enigma = self._s_type is SettingsType.ENIGMA_2
self._webtv_radio_button.set_visible(not is_enigma)
self._use_http_box.set_visible(is_enigma)
@@ -128,9 +156,9 @@ class DownloadDialog:
try:
if download:
if backup and d_type is not DownloadType.SATELLITES:
data_path = self._settings.data_local_path or self._data_path_entry.get_text()
data_path = self._settings.profile_data_path or self._data_path_entry.get_text()
os.makedirs(os.path.dirname(data_path), exist_ok=True)
backup_path = self._settings.backup_local_path or data_path + "backup/"
backup_path = self._settings.profile_backup_path or self._settings.default_backup_path
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)

View File

@@ -1,3 +1,31 @@
# -*- coding: utf-8 -*-
#
# The MIT License (MIT)
#
# Copyright (c) 2018-2021 Dmitriy Yefremov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Author: Dmitriy Yefremov
#
import gzip
import locale
import os
@@ -12,6 +40,7 @@ from gi.repository import GLib
from app.commons import run_idle, run_task
from app.connections import download_data, DownloadType
from app.eparser.ecommons import BouquetService, BqServiceType
from app.settings import SEP
from app.tools.epg import EPG, ChannelsParser
from app.ui.dialogs import get_message, show_dialog, DialogType, get_builder
from .main_helper import on_popup_menu, update_entry_data
@@ -480,7 +509,7 @@ class EpgDialog:
# ***************** Options *********************#
def init_options(self):
epg_dat_path = self._settings.data_local_path + "epg/"
epg_dat_path = "{}epg{}".format(self._settings.profile_data_path, SEP)
self._epg_dat_path_entry.set_text(epg_dat_path)
default_epg_data_stb_path = "/etc/enigma2"
epg_options = self._settings.epg_options

View File

@@ -1,3 +1,31 @@
# -*- coding: utf-8 -*-
#
# The MIT License (MIT)
#
# Copyright (c) 2018-2021 Dmitriy Yefremov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Author: Dmitriy Yefremov
#
""" Simple FTP client module. """
import subprocess
from collections import namedtuple
@@ -140,7 +168,7 @@ class FtpClientBox(Gtk.HBox):
@run_task
def init_file_data(self, path=None):
self.append_file_data(Path(path if path else self._settings.data_local_path))
self.append_file_data(Path(path if path else self._settings.profile_data_path))
@run_idle
def append_file_data(self, path: Path):

View File

@@ -618,7 +618,7 @@ class M3uImportDialog(IptvListDialog):
self._app = app
self._picons = app._picons
self._pic_path = app._settings.picons_local_path
self._pic_path = app._settings.profile_picons_path
self._services = None
self._url_count = 0
self._errors_count = 0

View File

@@ -632,7 +632,7 @@ class Application(Gtk.Application):
@run_idle
def update_picons_size(self):
self._picons_size = self._settings.list_picon_size
update_picons_data(self._settings.picons_local_path, self._picons, self._picons_size)
update_picons_data(self._settings.profile_picons_path, self._picons, self._picons_size)
self._fav_model.foreach(lambda m, p, itr: m.set_value(itr, Column.FAV_PICON, self._picons.get(
self._services.get(m.get_value(itr, Column.FAV_ID)).picon_id, None)))
self._services_model.foreach(lambda m, p, itr: m.set_value(itr, Column.SRV_PICON, self._picons.get(
@@ -1146,7 +1146,7 @@ class Application(Gtk.Application):
target_column = Column.FAV_ID if target is ViewTarget.FAV else Column.SRV_FAV_ID
srv = self._services.get(model[path][target_column], None)
if srv and srv.picon_id:
tooltip.set_icon(get_picon_pixbuf(self._settings.picons_local_path + srv.picon_id,
tooltip.set_icon(get_picon_pixbuf(self._settings.profile_picons_path + srv.picon_id,
size=self._settings.tooltip_logo_size))
tooltip.set_text(
self.get_hint_for_bq_list(srv) if target is ViewTarget.FAV else self.get_hint_for_srv_list(srv))
@@ -1588,8 +1588,8 @@ class Application(Gtk.Application):
if current_profile != self._settings.current_profile:
self.init_profiles(self._settings.current_profile)
data_path = self._settings.data_local_path if data_path is None else data_path
local_path = self._settings.data_local_path
data_path = self._settings.profile_data_path if data_path is None else data_path
local_path = self._settings.profile_data_path
os.makedirs(os.path.dirname(local_path), exist_ok=True)
if data_path != local_path:
@@ -1606,7 +1606,7 @@ class Application(Gtk.Application):
yield True
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_local_path, self._picons, self._picons_size)
update_picons_data(self._settings.profile_picons_path, self._picons, self._picons_size)
yield True
except FileNotFoundError as e:
msg = get_message("Please, download files from receiver or setup your path for read data!")
@@ -1820,8 +1820,8 @@ class Application(Gtk.Application):
def save_data(self, callback=None, ext_path=None):
self._save_tool_button.set_sensitive(False)
profile = self._s_type
path = ext_path or self._settings.data_local_path
backup_path = self._settings.backup_local_path
path = ext_path or self._settings.profile_data_path
backup_path = self._settings.profile_backup_path
# Backup data or clearing data path
backup_data(path, backup_path) if not ext_path and self._settings.backup_before_save else clear_data_path(path)
yield True
@@ -3290,7 +3290,7 @@ class Application(Gtk.Application):
@run_task
def update_picons(self):
update_picons_data(self._settings.picons_local_path, self._picons, self._picons_size)
update_picons_data(self._settings.profile_picons_path, self._picons, self._picons_size)
append_picons(self._picons, self._services_model)
def on_assign_picon(self, view, src_path=None, dst_path=None):

View File

@@ -1,3 +1,31 @@
# -*- coding: utf-8 -*-
#
# The MIT License (MIT)
#
# Copyright (c) 2018-2021 Dmitriy Yefremov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Author: Dmitriy Yefremov
#
""" Helper module for the ui. """
import os
import shutil
@@ -9,7 +37,7 @@ from gi.repository import GdkPixbuf, GLib
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 SettingsType
from app.settings import SettingsType, SEP
from .dialogs import show_dialog, DialogType, get_chooser_dialog
from .uicommons import ViewTarget, BqGenType, Gtk, Gdk, HIDE_ICON, LOCKED_ICON, KeyboardKey, Column
@@ -402,7 +430,7 @@ def assign_picons(target, srv_view, fav_view, transient, picons, settings, servi
picon_id = services.get(fav_id)[Column.SRV_PICON_ID]
if picon_id:
picons_path = dst_path or settings.picons_local_path
picons_path = dst_path or settings.profile_picons_path
os.makedirs(os.path.dirname(picons_path), exist_ok=True)
picon_file = picons_path + picon_id
try:
@@ -499,8 +527,8 @@ def remove_all_unused_picons(settings, picons, services):
def remove_picons(settings, picon_ids, picons):
pions_path = settings.picons_local_path
backup_path = settings.backup_local_path + "picons/"
pions_path = settings.profile_picons_path
backup_path = "{}{}{}".format(settings.profile_backup_path, "picons", SEP)
os.makedirs(os.path.dirname(backup_path), exist_ok=True)
for p_id in picon_ids:
picons[p_id] = None

View File

@@ -37,7 +37,7 @@ from gi.repository import GLib, GdkPixbuf, Gio
from app.commons import run_idle, run_task, run_with_delay
from app.connections import upload_data, DownloadType, download_data, remove_picons
from app.settings import SettingsType, Settings
from app.settings import SettingsType, Settings, SEP
from app.tools.picons import (PiconsParser, parse_providers, Provider, convert_to, download_picon, PiconsCzDownloader,
PiconsError)
from app.tools.satellites import SatellitesParser, SatelliteSource
@@ -184,7 +184,7 @@ class PiconManager(Gtk.Box):
# Settings
self._settings = settings
self._s_type = settings.setting_type
self._picons_dir_entry.set_text(self._settings.picons_local_path)
self._picons_dir_entry.set_text(self._settings.profile_picons_path)
self.pack_start(builder.get_object("picon_manager_frame"), True, True, 0)
self.show()
@@ -197,7 +197,7 @@ class PiconManager(Gtk.Box):
def on_picons_dest_view_realize(self, view):
self._services = {s.picon_id: s for s in self._app.current_services.values() if s.picon_id}
self._explorer_dest_path_button.select_filename(self._settings.picons_local_path)
self._explorer_dest_path_button.select_filename(self._settings.profile_picons_path)
def on_picons_src_changed(self, button):
self.update_picons_data(self._picons_src_view, button)
@@ -234,7 +234,7 @@ class PiconManager(Gtk.Box):
if self._terminate:
return
p_path = "{}/{}".format(path, file)
p_path = "{}{}{}".format(path, SEP, file)
p = self.get_pixbuf_at_scale(p_path, 72, 48, True)
if p:
yield model.append((p, file, p_path))
@@ -327,7 +327,7 @@ class PiconManager(Gtk.Box):
c_id = Column.SRV_FAV_ID
t_mod = target_view.get_model()
dest_path = self._explorer_dest_path_button.get_filename() + "/"
dest_path = self._explorer_dest_path_button.get_filename() + SEP
self.update_picons_dest_view(self._app.on_assign_picon(target_view, model[path][-1], dest_path))
self.show_assign_info([t_mod.get_value(t_mod.get_iter_from_string(itr), c_id) for itr in itr_str.split(",")])
@@ -371,7 +371,7 @@ class PiconManager(Gtk.Box):
if len(uris) == 2:
name, fav_id = self._current_picon_info
src = urlparse(unquote(uris[0])).path
dst = "{}/{}".format(urlparse(unquote(uris[1])).path, name)
dst = "{}{}{}".format(urlparse(unquote(uris[1])).path, SEP, name)
if src != dst:
shutil.copy(src, dst)
for row in get_base_model(self._picons_dest_view.get_model()):
@@ -443,7 +443,7 @@ class PiconManager(Gtk.Box):
return
settings = Settings(self._settings.settings)
settings.picons_local_path = "{}/".format(dest_path)
settings.profile_picons_path = "{}{}".format(dest_path, SEP)
self.show_info_message(get_message("Please, wait..."), Gtk.MessageType.INFO)
self.run_func(lambda: upload_data(settings=settings,
download_type=DownloadType.PICONS,
@@ -458,7 +458,7 @@ class PiconManager(Gtk.Box):
return
settings = Settings(self._settings.settings)
settings.picons_local_path = path + "/"
settings.profile_picons_path = path + SEP
self.run_func(lambda: download_data(settings=settings,
download_type=DownloadType.PICONS,
callback=self.append_output,

View File

@@ -52,7 +52,7 @@ class SatellitesTool(Gtk.Box):
super().__init__(*args, **kwargs)
self._app = app
self._data_path = settings.data_local_path + "satellites.xml"
self._data_path = settings.profile_data_path + "satellites.xml"
self._settings = settings
handlers = {"on_remove": self.on_remove,

View File

@@ -81,8 +81,8 @@ class ServiceDetailsDialog:
self._dialog.set_transient_for(transient)
self._s_type = settings.setting_type
self._tr_type = TrType.Satellite
self._satellites_xml_path = settings.data_local_path + "satellites.xml"
self._picons_dir_path = settings.picons_local_path
self._satellites_xml_path = settings.profile_data_path + "satellites.xml"
self._picons_path = settings.profile_picons_path
self._services_view = srv_view
self._fav_view = fav_view
self._action = action
@@ -504,13 +504,13 @@ class ServiceDetailsDialog:
Column.FAV_PICON: new_service.picon})
def update_picon_name(self, old_name, new_name):
if not os.path.isdir(self._picons_dir_path):
if not os.path.isdir(self._picons_path):
return
for file_name in os.listdir(self._picons_dir_path):
for file_name in os.listdir(self._picons_path):
if file_name == old_name:
old_file = os.path.join(self._picons_dir_path, old_name)
new_file = os.path.join(self._picons_dir_path, new_name)
old_file = os.path.join(self._picons_path, old_name)
new_file = os.path.join(self._picons_path, new_name)
os.rename(old_file, new_file)
break

View File

@@ -1199,7 +1199,7 @@ Author: Dmitriy Yefremov
<property name="row_spacing">5</property>
<property name="column_spacing">10</property>
<child>
<object class="GtkLabel" id="data_dir_label">
<object class="GtkLabel" id="data_path_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
@@ -1212,7 +1212,7 @@ Author: Dmitriy Yefremov
</packing>
</child>
<child>
<object class="GtkLabel" id="picons_dir_label">
<object class="GtkLabel" id="picons_path_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
@@ -1224,7 +1224,7 @@ Author: Dmitriy Yefremov
</packing>
</child>
<child>
<object class="GtkLabel" id="backup_dir_label">
<object class="GtkLabel" id="backup_path_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
@@ -1236,7 +1236,7 @@ Author: Dmitriy Yefremov
</packing>
</child>
<child>
<object class="GtkEntry" id="data_dir_field">
<object class="GtkEntry" id="data_path_field">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
@@ -1253,7 +1253,7 @@ Author: Dmitriy Yefremov
</packing>
</child>
<child>
<object class="GtkEntry" id="picons_dir_field">
<object class="GtkEntry" id="picons_path_field">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
@@ -1270,7 +1270,7 @@ Author: Dmitriy Yefremov
</packing>
</child>
<child>
<object class="GtkEntry" id="backup_dir_field">
<object class="GtkEntry" id="backup_path_field">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
@@ -1327,7 +1327,7 @@ Author: Dmitriy Yefremov
<property name="margin_bottom">5</property>
<property name="column_spacing">10</property>
<child>
<object class="GtkLabel" id="record_dir_label">
<object class="GtkLabel" id="record_path_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Streams record path:</property>
@@ -1339,7 +1339,7 @@ Author: Dmitriy Yefremov
</packing>
</child>
<child>
<object class="GtkEntry" id="record_data_dir_field">
<object class="GtkEntry" id="record_data_path_field">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>

View File

@@ -1,9 +1,37 @@
# -*- coding: utf-8 -*-
#
# The MIT License (MIT)
#
# Copyright (c) 2018-2021 Dmitriy Yefremov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Author: Dmitriy Yefremov
#
import os
import re
from app.commons import run_task, run_idle, log
from app.connections import test_telnet, test_ftp, TestException, test_http, HttpApiException
from app.settings import SettingsType, Settings, PlayStreamsMode, IS_LINUX
from app.settings import SettingsType, Settings, PlayStreamsMode, IS_LINUX, SEP
from app.ui.dialogs import show_dialog, DialogType, get_message, get_chooser_dialog, get_builder
from .main_helper import update_entry_data, scroll_to, get_picon_pixbuf
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, FavClickMode, DEFAULT_ICON, APP_FONT
@@ -78,6 +106,7 @@ class SettingsDialog:
self._http_use_ssl_check_button = builder.get_object("http_use_ssl_check_button")
self._telnet_port_field = builder.get_object("telnet_port_field")
self._telnet_timeout_spin_button = builder.get_object("telnet_timeout_spin_button")
self._reset_button = builder.get_object("reset_button")
# Test.
self._ftp_radio_button = builder.get_object("ftp_radio_button")
self._http_radio_button = builder.get_object("http_radio_button")
@@ -87,12 +116,13 @@ class SettingsDialog:
self._satellites_xml_field = builder.get_object("satellites_xml_field")
self._picons_paths_box = builder.get_object("picons_paths_box")
# Paths.
self._picons_dir_field = builder.get_object("picons_dir_field")
self._data_dir_field = builder.get_object("data_dir_field")
self._backup_dir_field = builder.get_object("backup_dir_field")
self._default_data_dir_field = builder.get_object("default_data_dir_field")
self._record_data_dir_field = builder.get_object("record_data_dir_field")
self._picons_path_field = builder.get_object("picons_path_field")
self._data_path_field = builder.get_object("data_path_field")
self._backup_path_field = builder.get_object("backup_path_field")
self._record_data_path_field = builder.get_object("record_data_path_field")
self._default_data_paths_switch = builder.get_object("default_data_paths_switch")
self._default_data_paths_switch.bind_property("active", self._backup_path_field, "sensitive", 4)
self._default_data_paths_switch.bind_property("active", self._picons_path_field, "sensitive", 4)
# Info bar.
self._info_bar = builder.get_object("info_bar")
self._message_label = builder.get_object("info_bar_message_label")
@@ -268,10 +298,10 @@ 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_paths_box.set_active_id(self._settings.picons_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._record_data_dir_field.set_text(self._settings.records_path)
self._data_path_field.set_text(self._settings.default_data_path)
self._picons_path_field.set_text(self._settings.default_picon_path)
self._backup_path_field.set_text(self._settings.default_backup_path)
self._record_data_path_field.set_text(self._settings.records_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)
@@ -328,9 +358,6 @@ 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_paths_box.get_active_id()
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()
def apply_settings(self, item=None):
if show_dialog(DialogType.QUESTION, self._dialog) != Gtk.ResponseType.OK:
@@ -348,7 +375,10 @@ class SettingsDialog:
self._ext_settings.show_bq_hints = self._bouquet_hints_switch.get_active()
self._ext_settings.show_srv_hints = self._services_hints_switch.get_active()
self._ext_settings.profile_folder_is_default = self._default_data_paths_switch.get_active()
self._ext_settings.records_path = self._record_data_dir_field.get_text()
self._ext_settings.default_data_path = self._data_path_field.get_text()
self._ext_settings.default_backup_path = self._backup_path_field.get_text()
self._ext_settings.default_picon_path = self._picons_path_field.get_text()
self._ext_settings.records_path = self._record_data_path_field.get_text()
self._ext_settings.activate_transcoding = self._transcoding_switch.get_active()
self._ext_settings.active_preset = self._presets_combo_box.get_active_id()
self._ext_settings.list_picon_size = int(self._picons_size_button.get_active_id())
@@ -515,29 +545,8 @@ class SettingsDialog:
if p_settings:
row[0] = new_value
self._profiles[new_value] = p_settings
self.update_local_paths(new_value, old_name)
self.on_profile_selected(self._profile_view, False)
def update_local_paths(self, p_name, old_name, force_rename=False):
data_path = self._settings.data_local_path
picons_path = self._settings.picons_local_path
backup_path = self._settings.backup_local_path
self._settings.data_local_path = p_name.join(data_path.rsplit(old_name, 1))
self._settings.picons_local_path = p_name.join(picons_path.rsplit(old_name, 1))
self._settings.backup_local_path = p_name.join(backup_path.rsplit(old_name, 1))
if force_rename:
try:
if os.path.isdir(picons_path):
os.rename(picons_path, self._settings.picons_local_path)
if os.path.isdir(data_path):
os.rename(data_path, self._settings.data_local_path)
if os.path.isdir(backup_path):
os.rename(backup_path, self._settings.backup_local_path)
except OSError as e:
self.show_info_message(str(e), Gtk.MessageType.ERROR)
def on_profile_selected(self, view, force=True):
if force:
self.on_apply_profile_settings()
@@ -566,6 +575,7 @@ class SettingsDialog:
def on_main_settings_visible(self, stack, param):
name = stack.get_visible_child_name()
self._apply_presets_button.set_visible(name == "streaming")
self._reset_button.set_visible(name == "profiles")
def on_http_use_ssl_toggled(self, button):
active = button.get_active()
@@ -706,7 +716,7 @@ class SettingsDialog:
@run_idle
def set_theme_thumbnail_image(self, theme_name):
img_path = "{}{}/gtk-3.0/thumbnail.png".format(self._ext_settings.themes_path, theme_name)
img_path = "{}{}{}gtk-3.0{}thumbnail.png".format(self._ext_settings.themes_path, theme_name, SEP, SEP)
self._theme_thumbnail_image.set_from_pixbuf(get_picon_pixbuf(img_path, 96))
def on_theme_add(self, button):