devedeng-extended/src/devedeng/configuration_data.py
Luna 6cddd72792 Default to all-but-one core for encoding
Using every core for a parallel batch starves the compositor and makes
the GUI show "not responding". Default multicore to cores-1 so the
desktop keeps headroom; the user can still raise it in Preferences.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 04:30:37 -07:00

313 lines
12 KiB
Python

#!/usr/bin/env python3
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of DeVeDe-NG
#
# DeVeDe-NG is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3
# as published by the Free Software Foundation.
#
# DeVeDe-NG is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from gi.repository import GObject
import os
import importlib.metadata
import platform
class configuration(GObject.GObject):
current_configuration = None
__gsignals__ = {'disc_type': (GObject.SIGNAL_RUN_FIRST, None, (str,))}
@staticmethod
def get_config():
if configuration.current_configuration is None:
configuration.current_configuration = configuration()
if (configuration.current_configuration._fill_config()):
configuration.current_configuration = None
return configuration.current_configuration
def __init__(self):
GObject.GObject.__init__(self)
self.version = str(importlib.metadata.version("devedeng"))
print("Version: " + self.version)
def _get_config_folder(self):
config_folder = os.environ.get("$XDG_CONFIG_HOME")
if config_folder is None:
config_folder = os.path.join(os.environ.get("HOME"), ".config")
config_folder = os.path.join(config_folder, "devedeng")
if not os.path.exists(config_folder):
os.makedirs(config_folder)
return config_folder
def _fill_config(self):
self.cores = os.cpu_count()
if 'sched_getaffinity' in dir(os):
self.cores = len(os.sched_getaffinity(0))
if platform.system() == 'FreeBSD':
self.cores = int(os.popen("sysctl -n kern.smp.cores").read().split('\n')[0])
self.log = ""
self.static_log = ""
self.disc_type = None
# try:
# os.stat("/usr/share/devedeng/wselect_disk.ui")
# is_local = False
# except:
# pass
# if is_local is None:
# try:
# os.stat("/usr/local/share/devedeng/wselect_disk.ui")
# is_local = True
# except:
# pass
# if is_local is None:
# return True
# else:
# if (is_local):
# # locales must be always at /usr/share/locale because
# # Gtk.Builder always search there
# self.share_locale = "/usr/share/locale"
# self.glade = "/usr/local/share/devedeng"
# self.pic_path = "/usr/local/share/devedeng"
# self.other_path = "/usr/local/share/devedeng"
# self.help_path = "/usr/local/share/doc/devedeng"
# else:
# self.share_locale = "/usr/share/locale"
# self.glade = "/usr/share/devedeng"
# self.pic_path = "/usr/share/devedeng"
# self.other_path = "/usr/share/devedeng"
# self.help_path = "/usr/share/doc/devedeng"
data_dir = os.path.join(os.path.dirname(__file__), 'data')
self.share_locale = os.path.join(data_dir, "locale")
self.glade = os.path.join(data_dir, "interface")
self.pic_path = os.path.join(data_dir, "pixmaps")
self.other_path = data_dir
self.help_path = os.path.join(data_dir, "doc")
self.gettext_domain = "devedeng"
self.PAL = True
self.tmp_folder = "/var/tmp"
# default to all-but-one core so a big parallel batch leaves the
# desktop responsive; the user can raise this in Preferences
self.multicore = max(1, self.cores - 1)
self.final_folder = os.environ.get("HOME")
self.sub_language = None
self.sub_codepage = None
self.film_analizer = None
self.film_player = None
self.film_converter = None
self.menu_converter = None
self.subtitles_font_size = 28
self.sub_language = None
self.sub_codepage = None
self.burner = None
self.mkiso = None
self.subt_fill_color = (1, 1, 1, 1)
self.subt_outline_color = (0, 0, 0, 1)
self.subt_outline_thickness = 0.0
# DVD encode profile: "compatibility" (CBR 4500k, old-player safe),
# "high" (2-pass VBR filling the disc), or "custom" (user bitrates).
self.encode_profile = "compatibility"
self.custom_video_kbps = 4500
self.custom_audio_kbps = 192
config_folder = self._get_config_folder()
config_path = os.path.join(config_folder, "devedeng.cfg")
if not os.path.exists(config_path):
# old config file
config_path = os.path.join(os.environ.get("HOME"), ".devedeng")
try:
config_data = open(config_path, "r")
for linea in config_data:
linea = linea.strip()
if linea == "":
continue
if linea[0] == "#":
continue
if linea[:13] == "video_format:":
if linea[13:].strip() == "pal":
self.PAL = True
elif linea[13:].strip() == "ntsc":
self.PAL = False
continue
if linea[:12] == "temp_folder:":
self.tmp_folder = linea[12:].strip()
continue
if linea[:10] == "multicore:":
self.multicore = int(linea[10:].strip())
continue
if linea[:13] == "final_folder:":
self.final_folder = linea[13:].strip()
continue
if linea[:13] == "sub_language:":
self.sub_language = linea[13:].strip()
continue
if linea[:13] == "sub_codepage:":
self.sub_codepage = linea[13:].strip()
continue
if linea[:14] == "film_analizer:":
self.film_analizer = linea[14:].strip()
continue
if linea[:12] == "film_player:":
self.film_player = linea[12:].strip()
continue
if linea[:15] == "film_converter:":
self.film_converter = linea[15:].strip()
continue
if linea[:15] == "menu_converter:":
self.menu_converter = linea[15:].strip()
continue
if linea[:7] == "burner:":
self.burner = linea[7:].strip()
continue
if linea[:6] == "mkiso:":
self.mkiso = linea[6:].strip()
continue
if linea[:19] == "subtitle_font_size:":
self.subtitles_font_size = int(linea[19:].strip())
continue
if linea[:20] == "subtitle_fill_color:":
c = linea[20:].strip().split(",")
self.subt_fill_color = (
float(c[0]), float(c[1]), float(c[2]), 1.0)
if linea[:23] == "subtitle_outline_color:":
c = linea[23:].strip().split(",")
self.subt_outline_color = (
float(c[0]), float(c[1]), float(c[2]), 1.0)
if linea[:27] == "subtitle_outilne_thickness:":
self.subt_outline_thickness = float(linea[27:].strip())
if linea[:15] == "encode_profile:":
profile = linea[15:].strip()
if profile in ("compatibility", "high", "custom"):
self.encode_profile = profile
continue
if linea[:18] == "custom_video_kbps:":
try:
self.custom_video_kbps = int(linea[18:].strip())
except ValueError:
pass
continue
if linea[:18] == "custom_audio_kbps:":
try:
self.custom_audio_kbps = int(linea[18:].strip())
except ValueError:
pass
continue
config_data.close()
except:
pass
return False
def set_disc_type(self, disc_type):
self.disc_type = disc_type
self.clear_static_log()
self.clear_log()
self.emit('disc_type', disc_type)
def save_config(self):
config_path = os.path.join(self._get_config_folder(), "devedeng.cfg")
try:
config_data = open(config_path, "w")
config_data.write("video_format:")
if (self.PAL):
config_data.write("pal\n")
else:
config_data.write("ntsc\n")
if (self.tmp_folder is not None):
config_data.write("temp_folder:" + str(self.tmp_folder) + "\n")
config_data.write("multicore:" + str(self.multicore) + "\n")
if (self.final_folder is not None):
config_data.write("final_folder:" +
str(self.final_folder) + "\n")
if (self.sub_language is not None):
config_data.write("sub_language:" +
str(self.sub_language) + "\n")
if (self.sub_codepage is not None):
config_data.write("sub_codepage:" +
str(self.sub_codepage) + "\n")
if (self.film_analizer is not None):
config_data.write("film_analizer:" +
str(self.film_analizer) + "\n")
if (self.film_player is not None):
config_data.write(
"film_player:" + str(self.film_player) + "\n")
if (self.film_converter is not None):
config_data.write("film_converter:" +
str(self.film_converter) + "\n")
if (self.menu_converter is not None):
config_data.write("menu_converter:" +
str(self.menu_converter) + "\n")
if self.burner is not None:
config_data.write("burner:" + str(self.burner) + "\n")
if self.mkiso is not None:
config_data.write("mkiso:" + str(self.mkiso) + "\n")
if (self.sub_codepage is not None):
config_data.write("sub_codepage:" +
str(self.sub_codepage) + "\n")
if (self.sub_language is not None):
config_data.write("sub_language:" +
str(self.sub_language) + "\n")
config_data.write("subtitle_font_size:" +
str(self.subtitles_font_size) + "\n")
config_data.write("subtitle_fill_color:" + str(self.subt_fill_color[0]) + "," + str(
self.subt_fill_color[1]) + "," + str(self.subt_fill_color[2]) + "\n")
config_data.write("subtitle_outline_color:" + str(self.subt_outline_color[0]) + "," + str(
self.subt_outline_color[1]) + "," + str(self.subt_outline_color[2]) + "\n")
config_data.write("subtitle_outilne_thickness:" +
str(self.subt_outline_thickness) + "\n")
config_data.write("encode_profile:" + str(self.encode_profile) + "\n")
config_data.write("custom_video_kbps:" +
str(self.custom_video_kbps) + "\n")
config_data.write("custom_audio_kbps:" +
str(self.custom_audio_kbps))
config_data.close()
# remove old configuration files
config_path = os.path.join(os.environ.get("HOME"), ".devedeng")
if os.path.exists(config_path):
os.remove(config_path)
except:
pass
def append_log(self, data, cr=True):
self.log += data
if (cr):
self.log += "\n"
def append_static_log(self, data, cr=True):
self.static_log += data
if (cr):
self.static_log += "\n"
def clear_log(self):
self.log = ""
def clear_static_log(self):
self.static_log = ""
def get_log(self):
return "Static data:\n\n" + self.static_log + "\n\nDynamic data:\n\n" + self.log