2016-12-04 18:09:15 +01:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
2016-12-11 00:05:32 +01:00
|
|
|
import gettext
|
2016-12-08 18:11:08 +01:00
|
|
|
import gi
|
|
|
|
import json
|
|
|
|
import locale
|
2016-12-04 18:09:15 +01:00
|
|
|
import os
|
2016-12-08 18:11:08 +01:00
|
|
|
import subprocess
|
2016-12-06 18:54:02 +01:00
|
|
|
import sys
|
2016-12-05 18:41:28 +01:00
|
|
|
import webbrowser
|
2016-12-04 18:09:15 +01:00
|
|
|
gi.require_version("Gtk", "3.0")
|
2016-12-11 18:12:01 +01:00
|
|
|
from gi.repository import Gtk, GdkPixbuf
|
2016-12-04 18:09:15 +01:00
|
|
|
|
2016-12-05 22:18:23 +01:00
|
|
|
class ManjaroHello():
|
2016-12-04 18:09:15 +01:00
|
|
|
def __init__(self):
|
2016-12-05 21:49:29 +01:00
|
|
|
# App vars
|
|
|
|
self.app = "manjaro-hello"
|
2016-12-06 18:54:02 +01:00
|
|
|
|
2016-12-04 22:48:13 +01:00
|
|
|
# Path vars
|
2016-12-18 11:18:08 +01:00
|
|
|
if os.path.basename(sys.argv[0]) == self.app:
|
2016-12-18 12:15:52 +01:00
|
|
|
self.data_path = "/usr/share/" + self.app + "/data/"
|
2016-12-10 17:34:29 +01:00
|
|
|
self.locale_path = "/usr/share/locale/"
|
2016-12-18 12:06:15 +01:00
|
|
|
self.ui_path = "/usr/share/" + self.app + "/ui/"
|
2016-12-11 18:12:01 +01:00
|
|
|
self.desktop_path = "/usr/share/applications/" + self.app + ".desktop"
|
2016-12-10 17:34:29 +01:00
|
|
|
else:
|
2016-12-17 19:14:39 +01:00
|
|
|
self.data_path = "data/"
|
|
|
|
self.locale_path = "locale/"
|
|
|
|
self.ui_path = "ui/"
|
2016-12-18 14:02:37 +01:00
|
|
|
self.desktop_path = os.getcwd() + "/" + self.app + ".desktop"
|
2016-12-11 18:12:01 +01:00
|
|
|
|
2016-12-10 17:34:29 +01:00
|
|
|
self.config_path = os.path.expanduser("~") + "/.config/"
|
|
|
|
self.preferences_path = self.config_path + self.app + ".json"
|
2016-12-18 00:05:56 +01:00
|
|
|
self.urls_path = self.data_path + "urls.json"
|
2016-12-10 17:34:29 +01:00
|
|
|
self.autostart_path = self.config_path + "autostart/" + self.app + ".desktop"
|
2016-12-15 14:56:21 +01:00
|
|
|
self.logo_path = "/usr/share/icons/manjaro.png"
|
2016-12-04 18:09:15 +01:00
|
|
|
|
2016-12-09 17:28:22 +01:00
|
|
|
# Load preferences
|
2016-12-04 18:09:15 +01:00
|
|
|
self.preferences = self.get_preferences()
|
2016-12-09 17:28:22 +01:00
|
|
|
|
2016-12-11 00:05:32 +01:00
|
|
|
# Load system infos
|
|
|
|
self.infos = get_infos()
|
|
|
|
|
2016-12-18 00:05:56 +01:00
|
|
|
# Load data files
|
|
|
|
self.urls = read_json(self.urls_path)
|
|
|
|
|
2016-12-11 00:05:32 +01:00
|
|
|
# Init window
|
|
|
|
self.builder = Gtk.Builder()
|
2016-12-11 18:12:01 +01:00
|
|
|
self.builder.add_from_file(self.ui_path + "manjaro-hello.glade")
|
2016-12-11 00:05:32 +01:00
|
|
|
self.builder.connect_signals(self)
|
|
|
|
self.window = self.builder.get_object("window")
|
|
|
|
|
2016-12-11 18:12:01 +01:00
|
|
|
# Load logos
|
2016-12-15 14:56:21 +01:00
|
|
|
logo = GdkPixbuf.Pixbuf.new_from_file_at_scale(self.logo_path, 75, 75, False)
|
2016-12-11 18:12:01 +01:00
|
|
|
self.window.set_icon_from_file(self.logo_path)
|
2016-12-15 14:56:21 +01:00
|
|
|
self.builder.get_object("manjaroicon").set_from_pixbuf(logo)
|
|
|
|
self.builder.get_object("aboutdialog").set_logo(logo)
|
2016-12-11 18:12:01 +01:00
|
|
|
|
2016-12-09 17:28:22 +01:00
|
|
|
# Init translation
|
2016-12-17 14:34:17 +01:00
|
|
|
self.default_locale = "en"
|
2016-12-11 01:05:01 +01:00
|
|
|
self.sys_locale = locale.getdefaultlocale()[0]
|
2016-12-11 00:05:32 +01:00
|
|
|
self.default_texts = {}
|
2016-12-09 17:28:22 +01:00
|
|
|
locales = os.listdir(self.locale_path)
|
|
|
|
locales.append(self.default_locale)
|
2016-12-17 23:07:03 +01:00
|
|
|
# Choose best locale for user
|
2016-12-09 17:28:22 +01:00
|
|
|
if self.preferences["locale"] not in locales:
|
|
|
|
if self.sys_locale in locales:
|
|
|
|
self.preferences["locale"] = self.sys_locale
|
|
|
|
else:
|
2016-12-17 14:37:41 +01:00
|
|
|
if self.sys_locale[:2] in locales:
|
|
|
|
self.preferences["locale"] = self.sys_locale[:2]
|
|
|
|
else:
|
|
|
|
self.preferences["locale"] = self.default_locale
|
2016-12-09 17:28:22 +01:00
|
|
|
|
2016-12-11 00:05:32 +01:00
|
|
|
# Select current locale in languages menu
|
|
|
|
self.builder.get_object("languages").set_active_id(self.preferences["locale"]);
|
|
|
|
self.builder.get_object("languages").connect("changed", self.on_languages_changed)
|
|
|
|
|
|
|
|
# Make translation
|
|
|
|
gettext.bindtextdomain(self.app, self.locale_path)
|
|
|
|
gettext.textdomain(self.app)
|
|
|
|
self.set_locale(self.preferences["locale"])
|
2016-12-09 17:28:22 +01:00
|
|
|
|
2016-12-17 23:07:03 +01:00
|
|
|
# Save used locale in config file
|
2016-12-09 17:28:22 +01:00
|
|
|
self.save_preferences()
|
2016-12-04 18:09:15 +01:00
|
|
|
|
2016-12-04 22:48:13 +01:00
|
|
|
# Set window subtitle
|
2016-12-06 18:54:02 +01:00
|
|
|
if self.infos["codename"] and self.infos["release"]:
|
|
|
|
self.builder.get_object("headerbar").props.subtitle = self.infos["codename"] + " " + self.infos["release"] + " "
|
|
|
|
self.builder.get_object("headerbar").props.subtitle += self.infos["arch"]
|
2016-12-04 18:09:15 +01:00
|
|
|
|
2016-12-10 17:34:29 +01:00
|
|
|
# Load images
|
2016-12-11 00:32:11 +01:00
|
|
|
for img in ("google+", "facebook", "twitter", "reddit"):
|
|
|
|
self.builder.get_object(img).set_from_file(self.data_path + "img/" + img + ".png")
|
2016-12-10 17:34:29 +01:00
|
|
|
|
2016-12-11 00:37:11 +01:00
|
|
|
# Set autostart switcher state
|
2016-12-18 15:34:43 +01:00
|
|
|
self.autostart = os.path.isfile(self.autostart_path)
|
|
|
|
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 self.infos["live"]:
|
2016-12-11 00:37:11 +01:00
|
|
|
self.builder.get_object("installlabel").set_visible(True)
|
2016-12-08 17:39:52 +01:00
|
|
|
if os.path.isfile("/usr/bin/calamares"):
|
|
|
|
self.builder.get_object("installgui").set_visible(True)
|
|
|
|
if os.path.isfile("/usr/bin/cli-installer"):
|
|
|
|
self.builder.get_object("installcli").set_visible(True)
|
|
|
|
|
|
|
|
self.window.show();
|
2016-12-04 18:09:15 +01:00
|
|
|
|
2016-12-11 00:38:36 +01:00
|
|
|
def set_locale(self, locale):
|
2016-12-17 23:19:05 +01:00
|
|
|
"""Set locale of ui and pages.
|
|
|
|
:param locale: locale to use
|
|
|
|
:type locale: str
|
|
|
|
"""
|
2016-12-11 00:05:32 +01:00
|
|
|
if self.preferences["locale"] != self.default_locale:
|
2016-12-11 00:38:36 +01:00
|
|
|
tr = gettext.translation(self.app, self.locale_path, [locale])
|
|
|
|
tr.install()
|
2016-12-11 00:05:32 +01:00
|
|
|
else:
|
|
|
|
gettext.install(self.app)
|
|
|
|
|
2016-12-17 23:07:03 +01:00
|
|
|
# Dirty code to fix an issue with gettext that can't translate strings from glade files
|
|
|
|
# Redfining all translatables strings
|
2016-12-11 00:05:32 +01:00
|
|
|
# TODO: Find a better solution
|
|
|
|
elts = {
|
2016-12-11 00:58:59 +01:00
|
|
|
"welcometitle": "label",
|
2016-12-17 13:46:13 +01:00
|
|
|
"welcomelabel": "label",
|
2016-12-11 00:58:59 +01:00
|
|
|
"firstcategory": "label",
|
|
|
|
"secondcategory": "label",
|
|
|
|
"thirdcategory": "label",
|
|
|
|
"readme": "label",
|
|
|
|
"release": "label",
|
|
|
|
"wiki": "label",
|
|
|
|
"involved": "label",
|
|
|
|
"forums": "label",
|
|
|
|
"chat": "label",
|
|
|
|
"mailling": "label",
|
|
|
|
"build": "label",
|
|
|
|
"donate": "label",
|
2016-12-11 00:05:32 +01:00
|
|
|
"installlabel": "label",
|
|
|
|
"installgui": "label",
|
|
|
|
"installcli": "label",
|
|
|
|
"autostartlabel": "label",
|
|
|
|
"aboutdialog": "comments"
|
|
|
|
}
|
|
|
|
for elt in elts:
|
|
|
|
if elt not in self.default_texts:
|
|
|
|
self.default_texts[elt] = getattr(self.builder.get_object(elt), "get_" + elts[elt])()
|
|
|
|
getattr(self.builder.get_object(elt), "set_" + elts[elt])(_(self.default_texts[elt]))
|
|
|
|
|
2016-12-17 00:07:49 +01:00
|
|
|
# Load pages
|
|
|
|
for page in ("readme", "release", "involved"):
|
|
|
|
self.builder.get_object(page + "label").set_markup(self.read_page(page))
|
|
|
|
|
2016-12-17 11:55:00 +01:00
|
|
|
def change_autostart(self, autostart):
|
2016-12-17 23:19:05 +01:00
|
|
|
"""Set state of autostart.
|
|
|
|
:param autostart: wanted autostart state
|
|
|
|
:type autostart: bool
|
|
|
|
"""
|
2016-12-17 11:55:00 +01:00
|
|
|
try:
|
|
|
|
if autostart and not os.path.isfile(self.autostart_path):
|
2016-12-05 21:49:29 +01:00
|
|
|
os.symlink(self.desktop_path, self.autostart_path)
|
2016-12-17 11:55:00 +01:00
|
|
|
elif not autostart and os.path.isfile(self.autostart_path):
|
2016-12-05 21:49:29 +01:00
|
|
|
os.unlink(self.autostart_path)
|
2016-12-17 11:55:00 +01:00
|
|
|
except OSError as e:
|
|
|
|
print(e)
|
2016-12-18 15:34:43 +01:00
|
|
|
self.autostart = autostart
|
2016-12-04 18:09:15 +01:00
|
|
|
|
|
|
|
def save_preferences(self):
|
2016-12-17 23:07:03 +01:00
|
|
|
"""Save preferences in config file."""
|
2016-12-04 18:09:15 +01:00
|
|
|
try:
|
|
|
|
with open(self.preferences_path, "w") as f:
|
|
|
|
json.dump(self.preferences, f)
|
2016-12-04 19:32:11 +01:00
|
|
|
except OSError as e:
|
2016-12-04 18:09:15 +01:00
|
|
|
print(e)
|
|
|
|
|
|
|
|
def get_preferences(self):
|
2016-12-17 23:07:03 +01:00
|
|
|
"""Read preferences from config file."""
|
2016-12-18 00:05:56 +01:00
|
|
|
preferences = read_json(self.preferences_path)
|
|
|
|
if not preferences:
|
2016-12-18 15:34:43 +01:00
|
|
|
preferences = {"locale": None}
|
2016-12-18 00:05:56 +01:00
|
|
|
return preferences
|
2016-12-04 18:09:15 +01:00
|
|
|
|
2016-12-05 19:32:15 +01:00
|
|
|
def read_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
|
|
|
|
"""
|
2016-12-10 17:34:29 +01:00
|
|
|
filename = self.data_path + "pages/{}/{}".format(self.preferences["locale"], name)
|
2016-12-04 20:40:34 +01:00
|
|
|
if not os.path.isfile(filename):
|
2016-12-10 17:34:29 +01:00
|
|
|
filename = self.data_path + "pages/{}/{}".format(self.default_locale, name)
|
2016-12-04 18:09:15 +01:00
|
|
|
try:
|
|
|
|
with open(filename, "r") as f:
|
|
|
|
return f.read()
|
2016-12-04 19:32:11 +01:00
|
|
|
except OSError as e:
|
2016-12-17 12:15:27 +01:00
|
|
|
return _("Can't load page.")
|
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-09 17:28:22 +01:00
|
|
|
self.preferences["locale"] = combobox.get_active_id()
|
2016-12-11 00:05:32 +01:00
|
|
|
self.set_locale(self.preferences["locale"])
|
2016-12-09 17:28:22 +01:00
|
|
|
self.save_preferences()
|
|
|
|
|
2016-12-17 12:21:15 +01:00
|
|
|
def on_action_clicked(self, action, _=None):
|
2016-12-17 23:07:03 +01:00
|
|
|
"""Event for differents actions."""
|
2016-12-17 12:21:15 +01:00
|
|
|
name = action.get_name()
|
2016-12-17 23:55:19 +01:00
|
|
|
if name == "installgui":
|
2016-12-08 18:11:08 +01:00
|
|
|
subprocess.call(["sudo", "-E", "calamares"])
|
2016-12-08 17:39:52 +01:00
|
|
|
elif name == "installcli":
|
2016-12-08 18:11:08 +01:00
|
|
|
subprocess.call(["sudo cli-installer"])
|
2016-12-17 12:21:15 +01:00
|
|
|
elif name == "autostart":
|
|
|
|
autostart = True if action.get_active() else False
|
|
|
|
self.change_autostart(autostart)
|
2016-12-17 12:08:40 +01:00
|
|
|
elif name == "about":
|
|
|
|
dialog = self.builder.get_object("aboutdialog")
|
|
|
|
dialog.set_transient_for(self.window)
|
|
|
|
dialog.run()
|
|
|
|
dialog.hide()
|
2016-12-04 18:09:15 +01:00
|
|
|
|
2016-12-17 23:55:19 +01:00
|
|
|
def on_btn_clicked(self, btn):
|
|
|
|
"""Event for clicked button."""
|
|
|
|
self.builder.get_object("stack").set_visible_child(self.builder.get_object(btn.get_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."""
|
2016-12-11 00:58:59 +01:00
|
|
|
webbrowser.open_new_tab(self.urls[link.get_name()])
|
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."""
|
2016-12-04 18:09:15 +01:00
|
|
|
Gtk.main_quit(*args)
|
|
|
|
|
2016-12-04 19:17:48 +01:00
|
|
|
def get_infos():
|
2016-12-17 23:19:05 +01:00
|
|
|
"""Get informations about user's system.
|
|
|
|
:return: informations about user's system
|
|
|
|
:rtype: dict
|
|
|
|
"""
|
2016-12-17 11:57:13 +01:00
|
|
|
lsb = get_lsb_infos()
|
2016-12-04 19:17:48 +01:00
|
|
|
infos = {}
|
2016-12-06 18:54:02 +01:00
|
|
|
infos["codename"] = lsb.get("CODENAME", None)
|
|
|
|
infos["release"] = lsb.get("RELEASE", None)
|
|
|
|
infos["arch"] = "64-bits" if sys.maxsize > 2**32 else "32-bits"
|
2016-12-08 17:39:52 +01:00
|
|
|
infos["live"] = os.path.exists("/bootmnt/manjaro") or os.path.exists("/run/miso/bootmnt/manjaro")
|
2016-12-04 19:17:48 +01:00
|
|
|
return infos
|
|
|
|
|
2016-12-17 11:57:13 +01:00
|
|
|
def get_lsb_infos():
|
2016-12-17 23:19:05 +01:00
|
|
|
"""Read informations from the lsb-release file.
|
|
|
|
:return: args from lsb-release file
|
|
|
|
:rtype: dict
|
|
|
|
"""
|
2016-12-04 19:10:33 +01:00
|
|
|
lsb = {}
|
|
|
|
try:
|
|
|
|
with open("/etc/lsb-release") as lsb_file:
|
|
|
|
for line in lsb_file:
|
|
|
|
if "=" in line:
|
|
|
|
var, arg = line.rstrip().split("=")
|
|
|
|
if var.startswith("DISTRIB_"):
|
|
|
|
var = var[8:]
|
|
|
|
if arg.startswith("\"") and arg.endswith("\""):
|
|
|
|
arg = arg[1:-1]
|
|
|
|
if arg:
|
|
|
|
lsb[var] = arg
|
2016-12-04 20:28:41 +01:00
|
|
|
except OSError as e:
|
|
|
|
print(e)
|
2016-12-04 19:10:33 +01:00
|
|
|
return lsb
|
|
|
|
|
2016-12-18 00:05:56 +01:00
|
|
|
def read_json(path):
|
|
|
|
try:
|
|
|
|
with open(path, "r") as f:
|
|
|
|
return json.load(f)
|
|
|
|
except OSError as e:
|
|
|
|
return None
|
|
|
|
|
2016-12-05 22:18:23 +01:00
|
|
|
if __name__ == "__main__":
|
|
|
|
ManjaroHello()
|
|
|
|
Gtk.main()
|