Files
euri-welcome/src/antergos_welcome.py
T

570 lines
21 KiB
Python
Raw Normal View History

2016-12-04 18:09:15 +01:00
#!/usr/bin/env python3
2018-08-22 18:33:43 +02:00
import collections
import glob
import urllib.request
2016-12-11 00:05:32 +01:00
import gettext
2018-09-23 13:49:19 +02:00
import gi
2016-12-08 18:11:08 +01:00
import json
import locale
2018-09-23 13:49:19 +02:00
import logging
2016-12-08 18:11:08 +01:00
import os
2017-05-25 17:05:49 +02:00
import subprocess
2016-12-08 18:11:08 +01:00
import sys
import webbrowser
2018-09-23 13:49:19 +02:00
2016-12-04 18:09:15 +01:00
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GdkPixbuf, Gdk, GLib
2018-08-22 18:33:43 +02:00
_SHARE_ANTERGOS = "/usr/share/antergos-next"
_HELLO_DATA_DIR = f"{_SHARE_ANTERGOS}/antergos-welcome"
2025-01-24 14:11:11 +00:00
_HELLO_PREF_FILE = f"{_HELLO_DATA_DIR}/preferences.json"
2018-08-22 18:33:43 +02:00
class EmbedManager:
"""manage included applications"""
def __init__(self, *args):
self.apps = []
self.count = 0
for app in args:
self.apps.append(app)
def get_modules(self, window: Gtk.Window):
for app in self.apps:
app.load(window)
self.count = sum((1 for x in self.apps if x.loaded))
def display(self, window: Gtk.Window):
for app in self.apps:
app.display(window)
class Embed:
"""abstact class for include app"""
def __init__(self):
""" abstact class initialisation """
self.name = "app" + self.__class__.__name__[5:]
self.loaded = False
self.box = None
def load(self, window: Gtk.Window) -> bool:
""" load modules if installed"""
raise Exception('abstract method')
def on_btn_clicked(self, btn, window: Gtk.Window):
"""Event for applications button."""
name = btn.get_name()
window.builder.get_object("stack").set_visible_child_name(name + "page")
def display(self, window: Gtk.Window):
""" show btn and add page"""
window.builder.get_object(self.name).set_visible(self.loaded)
if self.loaded:
window.builder.get_object("stack").add_named(self.box, self.name + "page")
class EmbedLayouts(Embed):
"""GNOME Layout Switcher"""
def load(self, window: Gtk.Window) -> bool:
try:
2025-01-24 14:11:11 +00:00
# import layoutswitcherlib
from layoutswitcherlib.layoutsbox import LayoutBox
try:
self.box = LayoutBox(window, usehello=True)
grid = Gtk.Grid()
grid.set_margin_start(15)
image = get_icon_image("go-previous", Gtk.IconSize.BUTTON)
2025-01-24 14:11:11 +00:00
back_btn=Gtk.Button(label=None, image=image)
back_btn.set_name("home")
back_btn.connect("clicked", self.on_btn_clicked,window)
grid.attach (back_btn, 0, 0, 1, 1)
self.box.pack_start(grid, expand=False, fill=False, padding=10)
self.box.reorder_child(grid,0)
2025-01-24 14:11:11 +00:00
self.box.show_all()
except Exception as err:
2025-01-24 14:11:11 +00:00
logging.error("Error in embedded application -> 'layoutswitcherlib'")
logging.error(err)
except ModuleNotFoundError:
logging.info(f"Plugin 'layoutswitcherlib' not available.")
self.loaded = self.box is not None
return self.loaded
class EmbedBrowser(Embed):
"""Application-utility"""
def load(self, window: Gtk.Window) -> bool:
try:
from application_utility import application_utility
from application_utility.translation import i18n
from application_utility.browser.application_browser import ApplicationBrowser
from application_utility.browser.exceptions import NoAppInIsoError
from application_utility.browser import alpm
from application_utility.browser import data
from application_utility.config.hello_config import HelloConfig
try:
conf = HelloConfig(application="antergos-welcome")
grid = Gtk.Grid()
grid.set_margin_start(5)
grid.set_margin_end(5)
grid.set_margin_top(5)
grid.set_margin_bottom(5)
image = get_icon_image("go-previous", Gtk.IconSize.BUTTON)
2025-01-24 14:11:11 +00:00
back_btn=Gtk.Button(label=None, image=image)
back_btn.set_name("home")
back_btn.connect("clicked", self.on_btn_clicked,window)
grid.attach (back_btn, 0, 1, 1, 1)
app=ApplicationBrowser(conf, window)
app.info_bar_title.pack_start(grid, expand=False, fill=False, padding=10)
app.info_bar_title.reorder_child(grid,0)
app.show_all()
self.box = app
except Exception as err:
2025-01-24 14:11:11 +00:00
logging.error("Error in embedded application -> 'application-utility'")
logging.error(err)
except ModuleNotFoundError as err:
2025-01-24 14:11:11 +00:00
logging.info(f"Plugin 'application-utility' not available.")
self.loaded = self.box is not None
return self.loaded
2018-08-22 18:33:43 +02:00
class Hello(Gtk.Window):
"""Hello"""
2017-02-04 11:00:52 +01:00
2016-12-04 18:09:15 +01:00
def __init__(self):
Gtk.Window.__init__(self, title="Antergos NeXT Welcome", border_width=6)
self.app = "antergos-welcome"
2021-07-10 17:47:13 +03:00
screen = Gdk.Screen.get_default()
2024-04-28 10:46:11 +01:00
self.dev = "--dev" in sys.argv
if self.dev:
2024-04-28 10:46:11 +01:00
# dont load hardcoded path in devmode
2025-01-24 14:11:11 +00:00
project_dir = os.getcwd()
self.preferences = read_json(f"{project_dir}/data/preferences.json")
self.preferences["data_path"] = f"{project_dir}/data"
self.preferences["desktop_path"] = f"{project_dir}/{self.app}.desktop"
self.preferences["locale_path"] = f"{project_dir}/locale"
self.preferences["ui_path"] = f"{project_dir}/ui/{self.app}.glade"
self.preferences["style_path"] = f"{project_dir}/ui/style.css"
logging.debug(f"Using dev preferences: {self.preferences}")
2017-05-07 18:33:51 +02:00
else:
2025-01-24 14:11:11 +00:00
self.preferences = read_json(f"{_HELLO_PREF_FILE}")
if not self.preferences:
self.preferences = read_json(f"{_HELLO_DATA_DIR}/data/preferences.json")
2025-01-24 14:11:11 +00:00
logging.debug(f"Using system preferences: {self.preferences}")
if not self.preferences:
logging.critical("Cannot find preferences.json — aborting")
sys.exit(1)
# Get saved infos
2025-01-24 14:11:11 +00:00
self.usr_prefs = read_json(self.preferences["save_path"])
if not self.usr_prefs:
self.usr_prefs = {"locale": None}
2016-12-18 00:05:56 +01:00
2021-07-15 16:32:54 +03:00
# Import Css
provider = Gtk.CssProvider()
provider.load_from_path(self.preferences["style_path"])
Gtk.StyleContext.add_provider_for_screen(screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
2016-12-11 00:05:32 +01:00
# Init window
self.builder = Gtk.Builder.new_from_file(self.preferences["ui_path"])
2016-12-11 00:05:32 +01:00
self.builder.connect_signals(self)
self.window = self.builder.get_object("window")
2021-07-11 11:52:19 +03:00
2017-05-09 20:00:16 +02:00
# Subtitle of headerbar
2017-06-16 16:30:08 +02:00
self.builder.get_object("headerbar").props.subtitle = ' '.join(get_lsb_infos())
2016-12-11 00:05:32 +01:00
2017-05-25 16:59:03 +02:00
# Load images
if os.path.isfile(self.preferences["logo_path"]):
logo = GdkPixbuf.Pixbuf.new_from_file(self.preferences["logo_path"])
2017-05-07 17:59:17 +02:00
self.window.set_icon(logo)
2017-05-07 18:41:28 +02:00
self.builder.get_object("distriblogo").set_from_pixbuf(logo)
2017-05-07 17:59:17 +02:00
self.builder.get_object("aboutdialog").set_logo(logo)
2016-12-11 18:12:01 +01:00
2017-05-25 16:59:03 +02:00
for btn in self.builder.get_object("social").get_children():
2025-01-24 14:11:11 +00:00
icon_path = self.preferences["data_path"] + "/img/" + btn.get_name() + ".png"
2017-05-25 16:59:03 +02:00
self.builder.get_object(btn.get_name()).set_from_file(icon_path)
for widget in self.builder.get_object("homepage").get_children():
2017-09-16 15:59:21 +02:00
if isinstance(widget, Gtk.Button) and \
2018-09-23 13:49:19 +02:00
widget.get_image_position() is Gtk.PositionType.RIGHT:
2017-05-25 17:03:35 +02:00
img = Gtk.Image.new_from_file(
2025-01-24 14:11:11 +00:00
self.preferences["data_path"] + "/img/external-link.png")
2019-11-27 21:44:44 +01:00
img.set_margin_start(2)
2017-05-25 16:59:03 +02:00
widget.set_image(img)
2016-12-26 18:12:17 +01:00
# Create pages
2025-01-24 14:11:11 +00:00
# load pageas for language
self.pages = os.listdir(f"/{self.preferences["data_path"]}/pages/{self.preferences["default_locale"]}")
2016-12-26 18:12:17 +01:00
for page in self.pages:
scrolled_window = Gtk.ScrolledWindow()
2017-02-04 16:18:08 +01:00
viewport = Gtk.Viewport(border_width=10)
2016-12-26 18:12:17 +01:00
label = Gtk.Label(wrap=True)
image = get_icon_image("go-previous", Gtk.IconSize.BUTTON)
2025-01-24 14:11:11 +00:00
back_btn=Gtk.Button(label=None, image=image)
back_btn.set_name("home")
back_btn.connect("clicked", self.on_btn_clicked)
2021-07-11 11:52:19 +03:00
grid = Gtk.Grid()
2025-01-24 14:11:11 +00:00
grid.attach (back_btn, 0, 1, 1, 1)
2021-07-11 11:52:19 +03:00
grid.attach(label, 1, 2, 1, 1)
viewport.add(grid)
2016-12-26 18:12:17 +01:00
scrolled_window.add(viewport)
2016-12-26 18:19:16 +01:00
scrolled_window.show_all()
2016-12-26 18:12:17 +01:00
self.builder.get_object("stack").add_named(scrolled_window, page + "page")
2016-12-09 17:28:22 +01:00
# Init translation
2016-12-11 00:05:32 +01:00
self.default_texts = {}
2025-01-24 14:11:11 +00:00
gettext.bindtextdomain(self.app, f"{self.preferences["locale_path"]}/")
2016-12-11 00:05:32 +01:00
gettext.textdomain(self.app)
2016-12-28 14:53:32 +01:00
self.builder.get_object("languages").set_active_id(self.get_best_locale())
2016-12-09 17:28:22 +01:00
2016-12-11 00:37:11 +01:00
# Set autostart switcher state
2017-06-22 05:49:53 +02:00
self.autostart = os.path.isfile(fix_path(self.preferences["autostart_path"]))
2016-12-18 15:34:43 +01:00
self.builder.get_object("autostart").set_active(self.autostart)
2016-12-11 00:37:11 +01:00
2016-12-08 17:39:52 +01:00
# Live systems
if (os.path.exists(self.preferences["live_path"])):
2025-01-24 14:11:11 +00:00
# show install label
2016-12-22 22:32:30 +01:00
self.builder.get_object("installlabel").set_visible(True)
2025-01-24 14:11:11 +00:00
# show install button
2016-12-26 17:29:24 +01:00
self.builder.get_object("install").set_visible(True)
GLib.timeout_add_seconds(5, self.auto_launch_installer)
2018-09-23 13:49:19 +02:00
# Installed systems
2018-08-22 18:33:43 +02:00
else:
manager = EmbedManager(EmbedBrowser(), EmbedLayouts())
manager.get_modules(self)
manager.display(self)
2023-08-21 21:47:24 +00:00
de = os.environ.get("DESKTOP_SESSION", "unknown")
2025-01-24 14:11:11 +00:00
# check desktop plasma or gnome
2023-08-21 21:47:24 +00:00
if de == "plasma" and os.path.isfile(self.preferences["plasmawelcome_path"]):
2025-01-24 14:11:11 +00:00
# enable Plasma Welcome button
2023-08-21 21:47:24 +00:00
self.builder.get_object("deWelcome").set_visible(True)
self.builder.get_object("deWelcome").set_label("Plasma Welcome")
elif de == "gnome" and os.path.isfile(self.preferences["gnometour_path"]):
2025-01-24 14:11:11 +00:00
# enable Gnome Tour button
2023-08-21 21:47:24 +00:00
self.builder.get_object("deWelcome").set_visible(True)
self.builder.get_object("deWelcome").set_label("GNOME Tour")
2016-12-08 17:39:52 +01:00
2016-12-26 18:19:16 +01:00
self.window.show()
self.play_welcome_song()
2026-06-20 20:47:58 +02:00
self.setup_mute_button()
def play_welcome_song(self):
song = "/usr/share/antergos-next-memes/its-raining-tacos.opus"
2026-06-20 20:47:58 +02:00
self.mpv_process = None
if os.path.isfile(song):
try:
2026-06-20 20:47:58 +02:00
self.mpv_process = subprocess.Popen(
["mpv", "--really-quiet", "--volume=55", song],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
except FileNotFoundError:
pass
2016-12-04 18:09:15 +01:00
2026-06-20 20:47:58 +02:00
def setup_mute_button(self):
mute_btn = self.builder.get_object("mute")
icon = Gtk.Image.new_from_icon_name("audio-volume-high", Gtk.IconSize.BUTTON)
mute_btn.set_image(icon)
def on_mute_clicked(self, btn):
if self.mpv_process and self.mpv_process.poll() is None:
self.mpv_process.terminate()
try:
self.mpv_process.wait(timeout=3)
except subprocess.TimeoutExpired:
self.mpv_process.kill()
btn.set_sensitive(False)
icon = Gtk.Image.new_from_icon_name("audio-volume-muted", Gtk.IconSize.BUTTON)
btn.set_image(icon)
dialog = Gtk.MessageDialog(
transient_for=self.window,
flags=0,
message_type=Gtk.MessageType.INFO,
buttons=Gtk.ButtonsType.OK,
text=":(",
)
dialog.format_secondary_text(
"You muted the welcome song...\n\nThe program is sad now."
)
dialog.run()
dialog.destroy()
2016-12-20 00:17:40 +01:00
def get_best_locale(self):
2025-01-24 14:11:11 +00:00
"""Choose locale, based on user's preferences.
2016-12-20 00:29:03 +01:00
:return: locale to use
:rtype: str
"""
2025-01-25 11:25:44 +09:00
path = self.preferences["locale_path"] + "/{}/LC_MESSAGES/" + self.app + ".mo"
2025-01-24 14:11:11 +00:00
if os.path.isfile(path.format(self.usr_prefs["locale"])):
# return usr_preference
return self.usr_prefs["locale"]
elif self.usr_prefs["locale"] == self.preferences["default_locale"]:
# return default
2017-05-25 21:08:35 +02:00
return self.preferences["default_locale"]
2016-12-20 00:17:40 +01:00
else:
2025-01-24 14:11:11 +00:00
# decide which locale to use
locale.setlocale(locale.LC_ALL, '')
sys_locale = locale.getlocale()[0]
2016-12-20 00:17:40 +01:00
# If user's locale is supported
2016-12-28 15:58:14 +01:00
if os.path.isfile(path.format(sys_locale)):
2017-02-05 11:15:04 +01:00
if "_" in sys_locale:
return sys_locale.replace("_", "-")
else:
return sys_locale
2016-12-20 00:17:40 +01:00
# If two first letters of user's locale is supported (ex: en_US -> en)
2016-12-28 15:58:14 +01:00
elif os.path.isfile(path.format(sys_locale[:2])):
return sys_locale[:2]
2016-12-20 00:17:40 +01:00
else:
return self.preferences["default_locale"]
2016-12-20 00:17:40 +01:00
2018-09-23 13:49:19 +02:00
def set_locale(self, use_locale):
2016-12-17 23:19:05 +01:00
"""Set locale of ui and pages.
2018-09-23 13:49:19 +02:00
:param use_locale: locale to use
:type use_locale: str
2016-12-17 23:19:05 +01:00
"""
2016-12-21 18:32:16 +01:00
try:
2025-01-24 14:11:11 +00:00
translation = gettext.translation(self.app,
self.preferences["locale_path"],
[use_locale],
fallback=True)
2017-09-16 15:59:21 +02:00
translation.install()
2016-12-21 18:32:16 +01:00
except OSError:
return
2016-12-11 00:05:32 +01:00
2025-01-24 14:11:11 +00:00
self.usr_prefs["locale"] = use_locale
2017-03-19 21:29:53 +01:00
2017-09-16 16:11:21 +02:00
# Real-time locale changing
2016-12-11 00:05:32 +01:00
elts = {
2018-09-23 13:49:19 +02:00
"comments": {"aboutdialog"},
2016-12-26 21:15:04 +01:00
"label": {
"autostartlabel",
2017-01-08 22:20:13 +01:00
"development",
2016-12-26 21:15:04 +01:00
"donate",
"firstcategory",
2017-05-25 16:14:54 +02:00
"forum",
2016-12-26 21:15:04 +01:00
"install",
"installlabel",
2024-04-28 10:58:13 +01:00
"rescue",
2016-12-26 21:15:04 +01:00
"involved",
"mailling",
"readme",
"release",
"secondcategory",
"thirdcategory",
"welcomelabel",
"welcometitle",
"wiki"
},
"tooltip_text": {
"about",
"development",
"donate",
"forum",
"mailling",
"wiki"
}
2016-12-11 00:05:32 +01:00
}
2016-12-26 21:15:04 +01:00
for method in elts:
2017-10-07 19:38:59 +02:00
if method not in self.default_texts:
self.default_texts[method] = {}
2016-12-26 21:15:04 +01:00
for elt in elts[method]:
if elt not in self.default_texts[method]:
self.default_texts[method][elt] = getattr(
2017-05-25 17:03:35 +02:00
self.builder.get_object(elt), "get_" + method)()
getattr(self.builder.get_object(elt), "set_" + method)(_(self.default_texts[method][elt]))
2016-12-11 00:05:32 +01:00
2016-12-26 18:12:17 +01:00
# Change content of pages
for page in self.pages:
child = self.builder.get_object("stack").get_child_by_name(page + "page")
2021-07-11 11:52:19 +03:00
label = child.get_children()[0].get_children()[0].get_children()[0]
2016-12-26 18:12:17 +01:00
label.set_markup(self.get_page(page))
2016-12-17 00:07:49 +01:00
2016-12-26 15:50:54 +01:00
def set_autostart(self, autostart):
2016-12-17 23:19:05 +01:00
"""Set state of autostart.
2025-01-24 14:11:11 +00:00
:param autostart: wanted auto start state
2016-12-17 23:19:05 +01:00
:type autostart: bool
"""
2016-12-17 11:55:00 +01:00
try:
2017-05-25 17:24:31 +02:00
if autostart and not os.path.isfile(fix_path(self.preferences["autostart_path"])):
os.symlink(self.preferences["desktop_path"],
fix_path(self.preferences["autostart_path"]))
elif not autostart and os.path.isfile(fix_path(self.preferences["autostart_path"])):
os.unlink(fix_path(self.preferences["autostart_path"]))
2016-12-26 15:50:54 +01:00
# Specific to i3
2017-05-25 17:24:31 +02:00
i3_config = fix_path("~/.i3/config")
2016-12-26 15:50:54 +01:00
if os.path.isfile(i3_config):
2016-12-26 20:27:16 +01:00
i3_autostart = "exec --no-startup-id " + self.app
2018-09-23 13:49:19 +02:00
with open(i3_config, "r+") as file:
content = file.read()
file.seek(0)
2016-12-26 15:50:54 +01:00
if autostart:
2018-09-23 13:49:19 +02:00
file.write(content.replace("#" + i3_autostart, i3_autostart))
2016-12-26 15:50:54 +01:00
else:
2018-09-23 13:49:19 +02:00
file.write(content.replace(i3_autostart, "#" + i3_autostart))
file.truncate()
2016-12-28 23:20:36 +01:00
self.autostart = autostart
2017-02-04 11:00:52 +01:00
except OSError as error:
print(error)
2016-12-04 18:09:15 +01:00
2016-12-26 17:30:23 +01:00
def get_page(self, name):
2016-12-17 23:19:05 +01:00
"""Read page according to language.
:param name: name of page (filename)
:type name: str
:return: text to load
:rtype: str
"""
2025-01-24 14:11:11 +00:00
filename = f"{self.preferences["data_path"]}/pages/{self.usr_prefs["locale"]}/{name}"
if not os.path.isfile(filename):
filename = f"{self.preferences["data_path"]}/pages/{self.preferences["default_locale"]}/{name}"
2016-12-04 18:09:15 +01:00
try:
2017-09-16 15:59:21 +02:00
with open(filename, "r") as fil:
return fil.read()
2016-12-21 18:34:34 +01:00
except OSError:
2016-12-17 12:15:27 +01:00
return _("Can't load page.")
2016-12-04 18:09:15 +01:00
def auto_launch_installer(self):
if not os.path.exists(self.preferences["live_path"]):
return False
self.window.hide()
subprocess.Popen(["sudo", "-E", "calamares-next"])
return False
2016-12-04 18:09:15 +01:00
# Handlers
2016-12-09 17:28:22 +01:00
def on_languages_changed(self, combobox):
2016-12-17 23:07:03 +01:00
"""Event for selected language."""
2016-12-28 14:53:32 +01:00
self.set_locale(combobox.get_active_id())
2016-12-09 17:28:22 +01:00
def on_action_clicked(self, action, _=None):
2016-12-17 23:07:03 +01:00
"""Event for differents actions."""
name = action.get_name()
2016-12-26 17:29:24 +01:00
if name == "install":
self.window.hide()
subprocess.Popen(["sudo", "-E", "calamares-next"])
elif name == "autostart":
self.set_autostart(action.get_active())
elif name == "about":
dialog = self.builder.get_object("aboutdialog")
dialog.run()
dialog.hide()
2023-08-21 21:47:24 +00:00
elif name == "deWelcome":
de = os.environ.get("DESKTOP_SESSION", "unknown")
if de == "plasma":
subprocess.Popen(["plasma-welcome"])
elif de == "gnome":
subprocess.Popen(["gnome-tour"])
def on_btn_clicked(self, btn):
2018-09-23 13:49:19 +02:00
"""Event for applications button."""
name = btn.get_name()
self.builder.get_object("stack").set_visible_child_name(name + "page")
2016-12-11 00:58:59 +01:00
def on_link_clicked(self, link, _=None):
2016-12-17 23:07:03 +01:00
"""Event for clicked link."""
2021-07-04 07:53:34 +00:00
Gtk.show_uri_on_window(None, self.preferences["urls"][link.get_name()], Gdk.CURRENT_TIME)
2016-12-05 18:41:28 +01:00
2016-12-04 18:09:15 +01:00
def on_delete_window(self, *args):
2016-12-17 23:07:03 +01:00
"""Event to quit app."""
2025-01-24 14:11:11 +00:00
write_json(self.preferences["save_path"], self.usr_prefs)
2016-12-04 18:09:15 +01:00
Gtk.main_quit(*args)
2016-12-21 06:35:54 -08:00
def fix_path(path):
2017-05-25 20:45:00 +02:00
"""Make good paths.
:param path: path to fix
:type path: str
:return: fixed path
:rtype: str
"""
if "~" in path:
path = path.replace("~", os.path.expanduser("~"))
return path
2025-01-24 14:11:11 +00:00
def read_json(path) -> dict or None:
2017-02-04 11:00:52 +01:00
"""Read content of a json file.
2017-05-25 20:45:00 +02:00
:param path: path to read
2017-05-21 20:38:21 +02:00
:type path: str
2017-02-04 11:00:52 +01:00
:return: json content
:rtype: str
"""
path = fix_path(path)
2016-12-18 00:05:56 +01:00
try:
2017-09-16 15:59:21 +02:00
with open(path, "r") as fil:
return json.load(fil)
2016-12-21 18:34:34 +01:00
except OSError:
2016-12-18 00:05:56 +01:00
return None
2017-05-21 20:38:21 +02:00
def write_json(path, content):
"""Write content in a json file.
2017-05-25 20:45:00 +02:00
:param path: path to write
2017-05-21 20:38:21 +02:00
:type path: str
:param content: content to write
:type path: str
"""
path = fix_path(path)
2017-05-21 20:38:21 +02:00
try:
2017-09-16 15:59:21 +02:00
with open(path, "w") as fil:
json.dump(content, fil)
2017-05-21 20:38:21 +02:00
except OSError as error:
print(error)
2016-12-21 06:35:54 -08:00
2018-08-22 18:33:43 +02:00
2017-06-16 16:30:08 +02:00
def get_lsb_infos():
2025-01-24 14:11:11 +00:00
"""Read information from the lsb-release file.
2017-06-16 16:30:08 +02:00
:return: args from lsb-release file
:rtype: dict"""
lsb = {}
try:
2018-09-23 13:49:19 +02:00
with open("/etc/lsb-release") as lsb_release:
for line in lsb_release:
2017-06-16 16:30:08 +02:00
if "=" in line:
var, arg = line.rstrip().split("=")
2019-11-24 16:26:25 +01:00
if not arg:
continue
var = var.replace("DISTRIB_","")
lsb[var] = arg.strip('"')
if lsb.get("CODENAME") and lsb.get("RELEASE"):
return lsb["CODENAME"], lsb["RELEASE"]
except (OSError, KeyError) as error:
print(error)
# Fall back to os-release
try:
with open("/usr/lib/os-release") as os_release:
for line in os_release:
if "=" in line:
var, arg = line.rstrip().split("=")
if not arg:
continue
lsb[var] = arg.strip('"')
return lsb.get("VERSION_CODENAME", "unknown"), lsb.get("VERSION_ID", "rolling")
2018-09-23 13:49:19 +02:00
except (OSError, KeyError) as error:
2017-06-16 16:30:08 +02:00
print(error)
return 'not Antergos NeXT', '0.0'
2017-06-16 16:30:08 +02:00
def get_icon_image(icon_name, icon_size):
icon_theme = Gtk.IconTheme.get_default()
if icon_theme.has_icon(icon_name):
pixbuf = icon_theme.load_icon(icon_name, icon_size, 0)
if pixbuf:
return Gtk.Image.new_from_pixbuf(pixbuf)
else:
return Gtk.Image.new_from_icon_name(icon_name, icon_size)
return None
2016-12-05 22:18:23 +01:00
if __name__ == "__main__":
2025-01-24 14:11:11 +00:00
logging.basicConfig(level=logging.INFO)
2018-08-22 18:33:43 +02:00
hello = Hello()
hello.connect('delete-event', Gtk.main_quit)
2018-08-22 18:33:43 +02:00
hello.connect("destroy", Gtk.main_quit)
2016-12-05 22:18:23 +01:00
Gtk.main()