diff --git a/launch.sh b/launch.sh
index 8bf29ab..7200f96 100755
--- a/launch.sh
+++ b/launch.sh
@@ -1,6 +1,8 @@
#!/bin/sh
# Script to generate mo files in a temp locale folder
# Use it only for testing purpose
+export PLUGIN_HELLO=True
+export PYTHONPATH="/home/fh/Data/projects/application-utility"
rm -rf locale
mkdir locale
cd po
diff --git a/src/app-install b/src/app-install
deleted file mode 100755
index c7dc46b..0000000
--- a/src/app-install
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/bin/bash
-
-# MIT License
-#
-# Copyright (c) 2018 Fredes Computer Service
-#
-# 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.
-
-#set -x
-if [[ -n ${APP_UTILITY} ]]; then
- echo "This script is part of Manjaro Application Utility\nIt is not meant to be run from command line\n exit()"
-fi
-
-# files
-IN_PKG_FILE="/tmp/.install-packages.txt"
-RM_PKG_FILE="/tmp/.remove-packages.txt"
-PM_STATUS_FILE="/tmp/.pm-status.txt"
-PM_LOCK_FILE="/var/lib/pacman/db.lck"
-
-echo ${IN_PKG_FILE}
-echo ${RM_PKG_FILE}
-
-# messages
-TITLE="Manjaro Application Utility"
-UPD_DB_MSG="Updating Package Database..."
-DB_LOCKED_MSG="Another package manager is running.\n
-If you are updating the system\n
-you MUST finish before continuing.\n
-If you are not, it is safe to kill the other process.\n
-What would you like to do?"
-KILL_PROCESS="Kill other process and continue"
-WAIT_PROCESS="Wait to finish updating"
-IN_WORKING_MSG="Installing Packages..."
-RM_WORKING_MSG="Uninstalling Packages..."
-DONE="Your System has Been Successfully Updated"
-
-if [[ -f ${IN_PKG_FILE} ]]; then
- IN_PKG=` cat ${IN_PKG_FILE} `
- echo ${IN_PKG}
-fi
-
-if [[ -f ${RM_PKG_FILE} ]]; then
- RM_PKG=` cat ${RM_PKG_FILE} `
- echo ${RM_PKG}
-fi
-
-# Make sure only root can run our script
-if [[ $EUID -ne 0 ]]; then
- echo "Superuser required ..." 1>&2
- exit 1
-fi
-
-# updating databases and writing results to a file
-pacman -Syy | tee ${PM_STATUS_FILE} | zenity --progress --title="${TITLE}" --no-cancel --pulsate --text "${UPD_DB_MSG}" --width=500 --auto-close
-
-PM_STATUS=` cat ${PM_STATUS_FILE} `
-
-# checking for other running package managers
-if [[ $(cat ${PM_STATUS_FILE} | grep -i 'core.db') = "" ]]
- then # giving choice to user to kill other process or wait
- ans=$(zenity --list --title="${TITLE}" --radiolist --text "${DB_LOCKED_MSG}" --column Select --column Choice TRUE "${KILL_PROCESS}" FALSE "${WAIT_PROCESS}" --width=500 --height=300)
- # killing pamac and unlocking db
- if [ "$ans" = "${KILL_PROCESS}" ]
- then
- killall pamac-updater
- killall pamac-manager
- rm ${PM_LOCK_FILE}
- pacman -Syy | zenity --progress --title="${TITLE}" --no-cancel --pulsate --text "${UPD_DB_MSG}" --width=500 --auto-close
- else # exiting according to user choice
- exit
- fi
-fi
-
-# Installing packages
-if [[ -n ${IN_PKG} ]]; then
- pacman -Syu --noconfirm ${IN_PKG} | zenity --progress --title="${TITLE}" --no-cancel --pulsate --text "${IN_WORKING_MSG}" --width=500 --auto-close
-fi
-
-# Uninstalling packages
-if [[ -n ${RM_PKG} ]]; then
- pacman -R --noconfirm ${RM_PKG} | zenity --progress --title="${TITLE}" --no-cancel --pulsate --text "${RM_WORKING_MSG}" --width=500 --auto-close
-fi
-
-# Letting user know that packages have been installed
-zenity --info --text="${DONE}" --width=500 --height=300
-
-# removing files no longer needed
-if [[ -f ${IN_PKG_FILE} ]]; then
- rm ${IN_PKG_FILE}
-fi
-
-if [[ -f ${RM_PKG_FILE} ]]; then
- rm ${RM_PKG_FILE}
-fi
-
-if [[ -f ${PM_STATUS_FILE} ]]; then
- rm ${PM_STATUS_FILE}
-fi
-
-if [[ -f ${PM_LOCK_FILE} ]]; then
- rm ${PM_LOCK_FILE}
-fi
diff --git a/src/app-utility b/src/app-utility
deleted file mode 100755
index 651e999..0000000
--- a/src/app-utility
+++ /dev/null
@@ -1,371 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
-# MIT License
-#
-# Copyright (c) 2018 Fredes Computer Service
-#
-# 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.
-
-import collections
-import json
-import glob
-import os
-import subprocess
-import sys
-import urllib.request
-
-import gi
-gi.require_version('Gtk', '3.0')
-from gi.repository import Gtk, GLib
-
-VERSION = "0.8"
-TITLE = "Manjaro Application Utility {}".format(VERSION)
-DEBUG = True
-
-GROUP = 0
-ICON = 1
-APPLICATION = 2
-DESCRIPTION = 3
-ACTIVE = 4
-PACKAGE = 5
-INSTALLED = 6
-
-
-class AppWindow(Gtk.Window):
- def __init__(self):
- Gtk.Window.__init__(self, title=TITLE, border_width=6)
- self.app = "app-utility"
- self.pref = {
- "data_set": "default",
- "conf_dir": "~/.config",
- "share_dir": "/usr/share/{}".format(self.app),
- "data_sets": ["default", "advanced"],
- "url": "https://gitlab.manjaro.org/fhdk/application-utility/raw/master"
- }
-
- self.dev = "--dev" in sys.argv
- if self.dev:
- self.pref["share_dir"] = "."
-
- self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
- GLib.set_prgname("{}".format(self.app))
- icon="system-software-install"
- pixbuf24 = Gtk.IconTheme.get_default().load_icon(icon, 24, 0)
- pixbuf32 = Gtk.IconTheme.get_default().load_icon(icon, 32, 0)
- pixbuf48 = Gtk.IconTheme.get_default().load_icon(icon, 48, 0)
- pixbuf64 = Gtk.IconTheme.get_default().load_icon(icon, 64, 0)
- pixbuf96 = Gtk.IconTheme.get_default().load_icon(icon, 96, 0)
- self.set_icon_list([pixbuf24, pixbuf32, pixbuf48, pixbuf64, pixbuf96])
-
- # set data
- self.app_store = None
- self.pkg_selected = None
- self.pkg_installed = None
- self.pkg_list_install = []
- self.pkg_list_removal = []
-
- # setup main box
- self.set_default_size(800, 650)
- self.application_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
- self.add(self.application_box)
-
- # create title box
- self.title_box = Gtk.Box()
- self.title_image = Gtk.Image()
- self.title_image.set_size_request(100, 100)
- self.title_image.set_from_file("/usr/share/icons/manjaro/maia/96x96.png")
- self.title_label = Gtk.Label()
- self.title_label.set_markup("Manjaro Application Maintenance\n"
- "Select/Deselect apps you want to install/remove.\n"
- "Click UPDATE SYSTEM button when ready.")
- self.title_box.pack_start(self.title_image, expand=False, fill=False, padding=0)
- self.title_box.pack_start(self.title_label, expand=True, fill=True, padding=0)
-
- # pack title box to main box
- self.application_box.pack_start(self.title_box, expand=False, fill=False, padding=0)
-
- # setup grid
- self.grid = Gtk.Grid()
- self.grid.set_column_homogeneous(True)
- self.grid.set_row_homogeneous(True)
- self.application_box.add(self.grid)
-
- # setup list store model
- self.app_store = self.load_app_data(self.pref["data_set"])
-
- # create a tree view with the model store
- self.tree_view = Gtk.TreeView.new_with_model(self.app_store)
- self.tree_view.set_activate_on_single_click(True)
-
- # column model: icon
- icon = Gtk.CellRendererPixbuf()
- column = Gtk.TreeViewColumn("", icon, icon_name=ICON)
- self.tree_view.append_column(column)
-
- # column model: group name column
- renderer = Gtk.CellRendererText()
- column = Gtk.TreeViewColumn("Group", renderer, text=GROUP)
- self.tree_view.append_column(column)
-
- # column model: app name column
- renderer = Gtk.CellRendererText()
- column = Gtk.TreeViewColumn("Application", renderer, text=APPLICATION)
- self.tree_view.append_column(column)
-
- # column model: description column
- renderer = Gtk.CellRendererText()
- column = Gtk.TreeViewColumn("Description", renderer, text=DESCRIPTION)
- self.tree_view.append_column(column)
-
- # column model: install column
- toggle = Gtk.CellRendererToggle()
- toggle.connect("toggled", self.on_app_toggle)
- column = Gtk.TreeViewColumn("Installed", toggle, active=ACTIVE)
- self.tree_view.append_column(column)
-
- # button box
- self.button_box = Gtk.Box(spacing=10)
- self.advanced = Gtk.ToggleButton(label="Advanced")
- self.advanced.connect("clicked", self.on_expert_clicked)
- self.download = Gtk.Button(label="download")
- self.download.connect("clicked", self.on_download_clicked)
- self.reload_button = Gtk.Button(label="reload")
- self.reload_button.connect("clicked", self.on_reload_clicked)
- self.update_system_button = Gtk.Button(label="UPDATE SYSTEM")
- self.update_system_button.connect("clicked", self.on_update_system_clicked)
- self.close_button = Gtk.Button(label="close")
- self.close_button.connect("clicked", Gtk.main_quit)
- self.button_box.pack_start(self.advanced, expand=False, fill=False, padding=10)
- self.button_box.pack_end(self.update_system_button, expand=False, fill=False, padding=10)
- self.button_box.pack_end(self.close_button, expand=False, fill=False, padding=10)
- self.button_box.pack_end(self.reload_button, expand=False, fill=False, padding=10)
- self.button_box.pack_end(self.download, expand=False, fill=False, padding=10)
- self.application_box.pack_end(self.button_box, expand=False, fill=False, padding=10)
-
- # create a scrollable window
- self.app_window = Gtk.ScrolledWindow()
- self.app_window.set_vexpand(True)
- self.app_window.add(self.tree_view)
- self.grid.attach(self.app_window, 0, 0, 5, len(self.app_store))
-
- # show start
- self.show_all()
-
- def load_app_data(self, data_set):
- if os.path.isfile("{}/{}.json".format(self.pref["conf_dir"], data_set)):
- app_data = self.read_json_file("{}/{}.json".format(self.pref["conf_dir"], data_set))
- else:
- app_data = self.read_json_file("{}/{}.json".format(self.pref["share_dir"], data_set))
-
- store = Gtk.TreeStore(str, str, str, str, bool, str, bool)
- for group in app_data:
- index = store.append(None,
- [group["name"],
- group["icon"],
- None, group["description"], None, None, None])
- for app in group["apps"]:
- status = self.app_installed(app["pkg"])
- tree_item = (None,
- app["icon"],
- app["name"],
- app["description"],
- status,
- app["pkg"],
- status)
- store.append(index, tree_item)
- return store
-
- def reload_app_data(self, dataset):
- self.pkg_selected = None
- self.pkg_installed = None
- self.pkg_list_install = []
- self.pkg_list_removal = []
- self.app_store.clear()
- self.app_store = self.load_app_data(dataset)
- self.tree_view.set_model(self.app_store)
-
- def on_reload_clicked(self, widget):
- self.reload_app_data(self.pref["data_set"])
-
- def on_expert_clicked(self, widget):
- if widget.get_active():
- self.pref["data_set"] = "advanced"
- else:
- self.pref["data_set"] = "default"
- self.reload_app_data(self.pref["data_set"])
-
- def on_download_clicked(self, widget):
- if self.net_check():
- # noinspection PyBroadException
- try:
- for download in self.pref["data_sets"]:
- url = "{}/{}.json".format(self.pref["url"], download)
- file = self.fix_path("{}/{}.json".format(self.pref["conf_dir"], download))
- req = urllib.request.Request(url=url)
- with urllib.request.urlopen(req, timeout=2) as response:
- data = json.loads(response.read().decode("utf8"))
- self.write_json_file(data, file)
-
- except Exception as e:
- print(e)
-
- else:
- dialog = Gtk.MessageDialog(self, 0,
- Gtk.MessageType.ERROR,
- Gtk.ButtonsType.CANCEL,
- "Download not available")
- dialog.format_secondary.text("The server 'gitlab.manjaro.org' could not be reached")
- dialog.run()
-
- def on_app_toggle(self, cell, path):
- # a group has no package attached and we don't install groups
- if self.app_store[path][PACKAGE] is not None:
- self.app_store[path][ACTIVE] = not self.app_store[path][ACTIVE]
- self.pkg_selected = self.app_store[path][PACKAGE]
- self.pkg_installed = self.app_store[path][INSTALLED]
-
- if self.app_store[path][ACTIVE] is False:
- if self.pkg_installed is True:
- # to uninstall
- self.pkg_list_removal.append(self.pkg_selected)
- if self.dev:
- print("for removal : {}".format(self.pkg_selected))
- if self.pkg_selected in self.pkg_list_install:
- # cancel install
- self.pkg_list_install.remove(self.pkg_selected)
- if self.dev:
- print("cancel install: {}".format(self.pkg_selected))
- else:
- # don't reinstall
- if self.pkg_installed is False:
- # only install
- if self.pkg_selected not in self.pkg_list_install:
- self.pkg_list_install.append(self.pkg_selected)
- if self.dev:
- print("to install : {}".format(self.pkg_selected))
- if self.pkg_selected in self.pkg_list_removal:
- # cancel uninstall
- self.pkg_list_removal.remove(self.pkg_selected)
- if self.dev:
- print("pkg list install: {}".format(self.pkg_list_install))
- print("pkg list removal: {}".format(self.pkg_list_removal))
-
- def on_update_system_clicked(self, widget):
- file_install = "/tmp/.install-packages.txt"
- file_uninstall = "/tmp/.remove-packages.txt"
-
- os.environ["APP_UTILITY"] = "PACKAGES"
- shell_fallback = False
-
- if self.pkg_list_install:
- if os.path.isfile("/usr/bin/pamac-installer"):
- subprocess.run(["pamac-installer"] + self.pkg_list_install)
- else:
- shell_fallback = True
- with open(file_install, "w") as outfile:
- for p in self.pkg_list_install:
- outfile.write("{} ".format(p))
-
- if self.pkg_list_removal:
- shell_fallback = True
- with open(file_uninstall, "w") as outfile:
- for p in self.pkg_list_removal:
- outfile.write("{} ".format(p))
-
- if shell_fallback:
- if self.dev:
- os.system('gksu-polkit ./app-install')
- else:
- os.system('gksu-polkit app-install')
-
- self.reload_app_data(self.pref["data_set"])
-
- @staticmethod
- def app_installed(package):
- if glob.glob("/var/lib/pacman/local/{}-[0-9]*".format(package)):
- return True
- return False
-
- @staticmethod
- def fix_path(path):
- """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
-
- @staticmethod
- def net_check():
- """Check for internet connection"""
- resp = None
- host = "https://gitlab.manjaro.org"
- # noinspection PyBroadException
- try:
- resp = urllib.request.urlopen(host, timeout=2)
- except Exception:
- pass
- return bool(resp)
-
- @staticmethod
- def read_json_file(filename, dictionary=True):
- """Read json data from file"""
- result = list()
- try:
- if dictionary:
- with open(filename, "rb") as infile:
- result = json.loads(
- infile.read().decode("utf8"),
- object_pairs_hook=collections.OrderedDict)
- else:
- with open(filename, "r") as infile:
- result = json.load(infile)
- except OSError:
- pass
- return result
-
- @staticmethod
- def write_json_file(data, filename, dictionary=False):
- """Writes data to file as json
- :param data
- :param filename:
- :param dictionary:
- """
- try:
- if dictionary:
- with open(filename, "wb") as outfile:
- json.dump(data, outfile)
- else:
- with open(filename, "w") as outfile:
- json.dump(data, outfile, indent=2)
- return True
- except OSError:
- return False
-
-
-if __name__ == "__main__":
- win = AppWindow()
- win.connect("delete-event", Gtk.main_quit)
- win.connect("destroy", Gtk.main_quit)
- win.show_all()
- Gtk.main()