# Reborn Maintenance App Trigger Handlers
# Created by Azaiel for RebornOS
# Maintained by Keegan for RebornOS
# This is an open-source project using Python3.  Feel free to use
# what you'd like, but please give credit!  Improvements are always welcome!
# RebornOS Discord: Azaiel
# RebornOS Discord: Keegan

# This ensures that the Gtk version is 3.0
import subprocess
import gi
import os
import time
import json
from datetime import date
from pathlib import Path
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
gi.require_version('Notify', '0.7')
from gi.repository import Notify
Notify.init("RebornOS FIRE")
try:
    import httplib
except:
    import http.client as httplib

# Create variables for both the current working directory and the location of the settings file
workingDirectory = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..'))
localeDirectory = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'TranslationFiles'))
settingsFile = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'Settings', 'settings.json'))
packageFile = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'Settings', 'packages.txt'))
runFile = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'Settings', 'neverRun.txt'))
startupFile = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'Bash', 'StartupChecks.sh'))
bashFile = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'Bash', 'Maintenance.sh'))
gladeFile = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'Glade', 'FIRE.glade'))
UnnecessaryFile = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'Python', 'RebornUnnecessary.py'))
SelectFile = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'Python', 'RebornSelect.py'))
RemoveFile = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'Python', 'RebornRemove.py'))
DowngradeFile = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'Python', 'RebornDowngrade.py'))
SettingsFile = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'Python', 'RebornSettings.py'))
MycroftDesktopFile = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'Mycroft', 'mycroft.desktop'))

installApricity = 'bash ' + workingDirectory + '/reborn-updates Apricity'
installPantheon = 'bash ' + workingDirectory + '/reborn-updates Pantheon'

# Update files that hold the lists of LigthDM and SDDM greeters + themes currently on the system, as well as the potential rollback opportunities
os.system('bash ' + startupFile + ' FirstTime ' + runFile + ' ' + packageFile + ' ' + SettingsFile + ' ' + workingDirectory)
os.system('bash ' + startupFile + ' DisplayLightDMgreeters ' + workingDirectory)
os.system('bash ' + startupFile + ' DisplaySDDMgreeters ' + workingDirectory)

# Check for Internet connection
conn = httplib.HTTPConnection("www.google.com", timeout=5)
try:
    conn.request("HEAD", "/")
    conn.close()
except:
    conn.close()
    Notify.Notification.new("Lacking Internet connection. Some options may not work").show()

# Create function for calculating unnecessary storage space
def TotalStorage():
    # Declare variables
    packageStorage = 0.0
    storageUnit = "K"
    # Store the space that Pacman's cache is taking up in kilobytes
    cacheStorage = subprocess.check_output("du -k /var/cache/pacman/pkg/ | awk '{print $1}'", shell=True)
    cacheStorage = float(cacheStorage.decode())
    # Store the space that the logs are taking up in kilobytes
    if os.path.exists("/run/log/journal"):
        journalStorage = subprocess.check_output("du -k /run/log/journal/ | awk '{print $1}' | sed -n '1p'", shell=True)
    else:
        journalStorage = subprocess.check_output("du -k /var/log/journal/ | awk '{print $1}' | sed -n '1p'", shell=True)
    if journalStorage.decode() == '':
        journalStorage = 0
    else:
        journalStorage = float(journalStorage.decode())

    # Iterate over every line in package-files.txt to calculate the sum of all the storage that the unnecessary packages are currently taking up
    os.system('pacman -Qdtq >' + workingDirectory + '/package-files.txt')
    with open(workingDirectory + '/package-files.txt', 'r') as packageFile:
        Lines = packageFile.readlines()
        for line in Lines:
            # Store the size of the package
            packageStorageTemp = subprocess.check_output("pacman -Qi " + line.strip() + " | grep 'Installed Size' | awk '{print $4}'", shell=True)
            packageStorageTemp = float(packageStorageTemp.strip().decode())
            # Store the unit that the size of the package is displayed in
            packageSize = subprocess.check_output("pacman -Qi " + line.strip() + " | grep 'Installed Size' | awk '{print $5}'", shell=True)
            packageSize = str(packageSize.strip().decode())
            # If the package size is displayed in MiB, convert it to KiB
            if packageSize == "MiB":
                packageStorageTemp = packageStorageTemp * 1024
            # If the package size is displayed in GiB, convert to KiB
            elif packageSize == "GiB":
                packageStorageTemp = packageStorageTemp * 1048576
            # Add the current package's size to the running total for the file
            packageStorage += packageStorageTemp

    # Add the cache, journal, and package sizes together for one number
    storageSaved = cacheStorage + journalStorage + packageStorage

    # If amount is at least as large as a gigabyte
    if storageSaved > 7812500:
        storageSaved = storageSaved / 7812500
        storageUnit = "GB"
    # If amount is at least as large as a Megabyte
    elif storageSaved > 7812.5:
        storageSaved = storageSaved / 7812.5
        storageUnit = "MB"
    # Round to 2 decimal places
    storageSaved = round(storageSaved, 2)

    # Return the amount saved along with its corrosponding unit
    return " " +  str(storageSaved) + " " + storageUnit

# Function that calculates current journal space
def JournalStorage():
    # Store the space that the logs are taking up in kilobytes
    if os.path.exists("/run/log/journal"):
        journalStorage = subprocess.check_output("du -k /run/log/journal/ | awk '{print $1}' | sed -n '1p'", shell=True)
    else:
        journalStorage = subprocess.check_output("du -k /var/log/journal/ | awk '{print $1}' | sed -n '1p'", shell=True)

    if journalStorage.decode() == '':
        journalStorage = 0
    else:
        journalStorage = float(journalStorage.decode())
        journalStorage = round(journalStorage, 2)
    return " (" + str(journalStorage) + " K)"

# Function that calculates current unnecessary cache space
def CacheStorage():
    # Store the space that Pacman's cache is taking up in kilobytes
    cacheStorage = subprocess.check_output("du -k /var/cache/pacman/pkg/ | awk '{print $1}'", shell=True)
    cacheStorage = float(cacheStorage.decode())

    storageUnit = "KB"
    # If amount is at least as large as a gigabyte
    if cacheStorage > 7812500:
        cacheStorage = cacheStorage / 7812500
        storageUnit = "GB"
    # If amount is at least as large as a Megabyte
    elif cacheStorage > 7812.5:
        cacheStorage = cacheStorage / 7812.5
        storageUnit = "MB"

    cacheStorage = round(cacheStorage, 2)
    return " (" + str(cacheStorage) + " " + storageUnit + ")"

# Function that calculates current unnecessary cache space
def PackageStorage():
    packageStorage = 0.0
    # Iterate over every line in package-files.txt to calculate the sum of all the storage that the unnecessary packages are currently taking up
    os.system('pacman -Qdtq >' + workingDirectory + '/package-files.txt')
    with open(workingDirectory + '/package-files.txt', 'r') as packageFile:
        Lines = packageFile.readlines()
        for line in Lines:
            # Store the size of the package
            packageStorageTemp = subprocess.check_output("pacman -Qi " + line.strip() + " | grep 'Installed Size' | awk '{print $4}'", shell=True)
            packageStorageTemp = float(packageStorageTemp.strip().decode())
            # Store the unit that the size of the package is displayed in
            packageSize = subprocess.check_output("pacman -Qi " + line.strip() + " | grep 'Installed Size' | awk '{print $5}'", shell=True)
            packageSize = str(packageSize.strip().decode())
            # If the package size is displayed in MiB, convert it to KiB
            if packageSize == "MiB":
                packageStorageTemp = packageStorageTemp * 1024
            # If the package size is displayed in GiB, convert to KiB
            elif packageSize == "GiB":
                packageStorageTemp = packageStorageTemp * 1048576
            # Add the current package's size to the running total for the file
            packageStorage += packageStorageTemp

    storageUnit = "KB"
    # If amount is at least as large as a gigabyte
    if packageStorage > 7812500:
        packageStorage = packageStorage / 7812500
        storageUnit = "GB"
    # If amount is at least as large as a Megabyte
    elif packageStorage > 7812.5:
        packageStorage = packageStorage / 7812.5
        storageUnit = "MB"

    packageStorage = round(packageStorage, 2)
    return " (" + str(packageStorage) + " " + storageUnit + ")"

# Create Handlers (Triggers) for each item
class Handler:
    def __init__(self):
        self.listoptions1 = [0,0,0,0]
        self.listoptions2 = [0,0,0,0,0]
        # Create settings file if it does not already exist, as well as declare the self.settings array
        if not os.path.isfile(settingsFile):
            self.settings = {
                "terminal": "",
                "chosen_date": {
                    "day": 0,
                    "month": 0,
                    "year": 0
                }
            }
            with open(settingsFile, 'w+') as outfile:
                outfile.write(json.dumps(self.settings, indent = 4))
        else:
            with open(settingsFile) as outfile:
                self.settings = json.load(outfile)

# Close the window
    def onDestroy(self, *args):
        Gtk.main_quit()

################################################################################
############################### Top Menu ######################################
################################################################################

# Launch the settings window
    def RebornSettings(self, button):
        os.system('python3 ' + SettingsFile)

################################################################################
############################### First Tab ######################################
################################################################################

# Test a LightDM Greeter
    def LightDMTestGreeter(self, combo):
        tree_iter = combo.get_active_iter()
        if tree_iter is not None:
            model = combo.get_model()
            chosenGreeter = model[tree_iter][0]
            os.system('bash ' + bashFile + ' TestLightdm ' + chosenGreeter)

# Set LightDM as default
    def LightDMdefault(self, button):
        os.system('pkexec bash ' + bashFile + ' LightDMdefault')
        Notify.Notification.new("LightDM set as default").show()

# Set SDDM as default
    def SDDMdefault(self, button):
        os.system('pkexec bash ' + bashFile + ' SDDMdefault')
        Notify.Notification.new("SDDM set as default").show()

# Test LightDM Greeter
    def LightDMTestGreeter(self, combo):
        tree_iter = combo.get_active_iter()
        if tree_iter is not None:
            model = combo.get_model()
            chosenGreeter = model[tree_iter][0]
            os.system('bash ' + bashFile + ' LightDMdefault ' + chosenGreeter)

# Set LightDM Greeter
    def LightDMUseGreeter(self, combo):
        tree_iter = combo.get_active_iter()
        if tree_iter is not None:
            model = combo.get_model()
            chosenGreeter = model[tree_iter][0]
            os.system('pkexec bash ' + bashFile + ' LightDM ' + chosenGreeter)
            Notify.Notification.new("LightDM greeter changed").show()

# Test SDDM Greeter
    def SDDMTestGreeter(self, combo):
        tree_iter = combo.get_active_iter()
        if tree_iter is not None:
            model = combo.get_model()
            chosenGreeter = model[tree_iter][0]
            os.system('sddm-greeter --test-mode --theme /usr/share/sddm/themes/' + chosenGreeter)

# Set SDDM Greeter
    def SDDMUseGreeter(self, combo):
        tree_iter = combo.get_active_iter()
        if tree_iter is not None:
            model = combo.get_model()
            chosenGreeter = model[tree_iter][0]
            os.system('pkexec bash ' + bashFile + ' SDDM ' + chosenGreeter)
            Notify.Notification.new("SDDM greeter changed").show()

################################################################################
############################### Second Tab ######################################
################################################################################

# Install Apricity
    def clickApricity(self, button):
        subprocess.Popen(['xterm', '-e', installApricity])

    # Install Budgie
    def clickBudgie(self, button):
        os.system('bash ' + bashFile + ' DesktopEnvironment budgie ' + self.settings["terminal"])

    # Install Cinnamon
    def clickCinnamon(self, button):
        os.system('bash ' + bashFile + ' DesktopEnvironment cinnamon ' + self.settings["terminal"])

    # Install Deepin
    def clickDeepin(self, button):
        os.system('bash ' + bashFile + ' DesktopEnvironment deepin ' + self.settings["terminal"])

    # Install Enlightenment
    def clickEnlightenment(self, button):
        os.system('bash ' + bashFile + ' DesktopEnvironment enlightenment ' + self.settings["terminal"])

    # Install GNOME
    def clickGnome(self, button):
        os.system('bash ' + bashFile + ' DesktopEnvironment gnome ' + self.settings["terminal"])

    # Install i3
    def clicki3(self, button):
        os.system('bash ' + bashFile + ' DesktopEnvironment i3 ' + self.settings["terminal"])

    # Install Plasma
    def clickPlasma(self, button):
        os.system('bash ' + bashFile + ' DesktopEnvironment plasma ' + self.settings["terminal"])

    # Install LXQt
    def clickLXQt(self, button):
        os.system('bash ' + bashFile + ' DesktopEnvironment lxqt ' + self.settings["terminal"])

    # Install Mate
    def clickMate(self, button):
        os.system('bash ' + bashFile + ' DesktopEnvironment mate ' + self.settings["terminal"])

    # Install Openbox
    def clickOpenbox(self, button):
        os.system('bash ' + bashFile + ' DesktopEnvironment openbox ' + self.settings["terminal"])

    # Install Pantheon
    def clickPantheon(self, button):
        os.system('bash ' + bashFile + ' DesktopEnvironment pantheon ' + self.settings["terminal"])

    # Install XFCE
    def clickXFCE(self, button):
        os.system('bash ' + bashFile + ' DesktopEnvironment xfce ' + self.settings["terminal"])

################################################################################
############################### Third Tab ######################################
################################################################################

    # Select the general option
    def onRemoveAll(self, switch,state):
        if state == True:
            # Set all the below switches to "True"
            builder.get_object("goClearCache").set_active("True")
            builder.get_object("goCleanJourna").set_active("True")
            builder.get_object("goUnnecessaryPrograms").set_active("True")

    # Clear Pacman's cache completely
    def onClearCache(self, switch, state):
        if state == True:
            self.listoptions1[0]=1
        else:
            self.listoptions1[0]=0
            builder.get_object("goRemoveAll").set_active(False)

    # Clean the system journal excepting the last 3 days worth of text
    def onCleanJournal(self, switch, state):
        if state == True:
            self.listoptions1[1]=1
        else:
            self.listoptions1[1]=0
            builder.get_object("goRemoveAll").set_active(False)

    # Allow the user to remove programs that are no longer necessary - orphans, depreciated, etc
    def onUnnecessaryPrograms(self, switch, state):
        if state == True:
            self.listoptions1[2]=1
        else:
            self.listoptions1[2]=0
            builder.get_object("goRemoveAll").set_active(False)

    # Rank the mirrors
    def onRankMirrors(self, switch, state):
        if state == True:
            self.listoptions1[3]=1
        else:
            self.listoptions1[3]=0

    # Apply select changes from above
    def clickApply1(self, button):
        print(self.listoptions1)
        if self.listoptions1[0] == 1:
            print("Clearing Cache...")

        if self.listoptions1[1] == 1:
            print("Cleaning Journal...")

        if self.listoptions1[3] == 1:
            print("Ranking Mirrors...")
            Notify.Notification.new("Ranking Mirrors...").show()

        # Clear cache, clean journal, and rank mirrors
        if self.listoptions1[0] == 1 or self.listoptions1[1] == 1 or self.listoptions1[3] == 1:
            os.system( "pkexec " + bashFile + " CleaningOptions " + str(self.listoptions1[0]) + ' ' + str(self.listoptions1[1]) +  ' ' + str(self.listoptions1[3]))

        # Run Python3 command
        if self.listoptions1[2] == 1:
            # If the file containing the list of packages that can be removed is empty, show the below command.
            if os.stat(workingDirectory + "/package-files.txt").st_size == 0:
                Notify.Notification.new("No Unnecessary Packages to Remove").show()
            # Otherwise, show the dialog window to remove those unnecessary packages
            else:
                os.system("python3 " + UnnecessaryFile)

        # Display "Done" message
        if self.listoptions1[0] == 1 or self.listoptions1[1] == 1 or self.listoptions1[2] == 1 or self.listoptions1[3] == 1:
            Notify.Notification.new("Done!").show()

################################################################################
############################### Fourth Tab #####################################
################################################################################

    def onSaveRecoverPackages(self, switch, state):
        if state == True:
            self.listoptions2[0]=1
        else:
            self.listoptions2[0]=0

    def onRebuildGrub(self, switch, state):
        if state == True:
            self.listoptions2[1]=1
        else:
            self.listoptions2[1]=0

    def onReinstallGrubEFI(self, switch, state):
        if state == True:
            self.listoptions2[2]=1
        else:
            self.listoptions2[2]=0

    def onDowngrade(self, switch, state):
        if state == True:
            self.listoptions2[3]=1
        else:
            self.listoptions2[3]=0

    def onRemovePackage(self, switch, state):
        if state == True:
            self.listoptions2[4]=1
        else:
            self.listoptions2[4]=0

    def clickApply2(self, button):
        print(self.listoptions2)
        if self.listoptions2[0] == 1:
            print("Save/Recover Packages...")
            os.system('python3 ' + SelectFile)
            Notify.Notification.new("Operation Complete").show()

        if self.listoptions2[1] == 1:
            print("Reinstalling Grub...")
            Notify.Notification.new("Reinstalling Grub...").show()
            os.system('pkexec pacman -S grub --noconfirm')
            Notify.Notification.new("Grub has Been Reinstalled").show()

        if self.listoptions2[2] == 1:
            print("Rebuilding Grub (EFI)...")
            os.system('pkexec bash ' + bashFile + ' Grub')
            Notify.Notification.new("Grub is Rebuilt").show()

        if self.listoptions2[3] == 1:
            print("Downgrading interface started...")
            os.system('python3 ' + DowngradeFile)
            Notify.Notification.new("Package Downgraded").show()

        if self.listoptions2[4] == 1:
            print("Package Removal interface started...")
            os.system('python3 ' + RemoveFile)
            Notify.Notification.new("Package Removed").show()

################################################################################
############################### Fifth Tab ######################################
################################################################################

    def setRollbackDate(self, selectedDate):
        # Record the full date that has been selected by the user
        rollbackDate = builder.get_object("RollbackCalendar").get_date()
        rollbackDate = " ".join([str(i) for i in rollbackDate])
        # Extract the year from the selected date
        rollbackYear = rollbackDate.split(' ')[0]

        # Extract the month from the selected date. By default, it is numerically 1 lower in value than it should be.
        rollbackMonth = str(int(rollbackDate.split(' ')[1]) + 1)
        # If the month is not a double-digit value, we must manually tack on a leading 0
        if int(rollbackMonth) < 10:
            rollbackMonth = '0' + rollbackMonth

        # Extract the day from the selected date
        rollbackDay = rollbackDate.split(' ')[2]
        # If the day is not a double-digit value, we must manually tack on a leading 0
        if int(rollbackDay) < 10:
            rollbackDay = '0' + rollbackDay

        # Since we have modified the month and day values, just use our 3 values as an updated rollbackDate value
        rollbackDate = rollbackYear + rollbackMonth + rollbackDay

        # If the date selected is in the future, prevent the user from using said date
        if int(rollbackDate.replace(" ", "")) > int(str(date.today()).replace("-", "")):
            Notify.Notification.new("Cannot Rollback to the Future").show()
            builder.get_object("RollbackCalendar").set_property("day", date.today().day)
            builder.get_object("RollbackCalendar").set_property("month", date.today().month - 1)
            builder.get_object("RollbackCalendar").set_property("year", date.today().year)
        # If the date selected is before Arch Linux began archiving their packages, replace the selected date with the earliest possible
        elif int(rollbackDate.replace(" ", "")) < 20130831:
            Notify.Notification.new("Archives did NOT exist before August 31, 2013").show()
            builder.get_object("RollbackCalendar").set_property("day", 31)
            builder.get_object("RollbackCalendar").set_property("month", 7)
            builder.get_object("RollbackCalendar").set_property("year", 2013)
        # If neither of the two above cases were true, then save the date in the settings file
        else:
            self.settings["chosen_date"]["day"] = int(rollbackDay)
            self.settings["chosen_date"]["month"] = int(rollbackMonth)
            self.settings["chosen_date"]["year"] = int(rollbackYear)
            # Update values in JSON settings file
            with open(settingsFile, 'w+') as outfile:
                outfile.write(json.dumps(self.settings, indent = 4))

    def rollbackUse(self, button):
        os.system('pkexec bash ' + bashFile + ' Rollback ' + self.settings["chosen_date"]["day"] + ' ' + self.settings["chosen_date"]["month"] + ' ' + self.settings["chosen_date"]["year"] + ' ' + self.settings["terminal"])
        Notify.Notification.new("Rollback Complete. Please Reboot for Full Effect").show()

    def resetRollbackUse(self, button):
        os.system('bash ' + bashFile + ' ResetRollback ' + self.settings["terminal"])

################################################################################
############################### Sixth Tab ######################################
################################################################################

    # Control Mycroft
    def clickControlMycroft(self, button):
        # Check to see if Mycroft/s desktop file already is already in place
        mycroftFile = Path("/usr/share/applications/mycroft.desktop")
        if mycroftFile.exists():
            os.system('pkexec bash ' + bashFile + ' RemoveMycroft ' + self.settings["terminal"])
            # Inform the user by updating the button label
            builder.get_object("Mycroft").set_label(locale["RebornOSFIRE"]["ProgramsTab"]["AddonsTab"]["ControlMycroft"])
        else:
            os.system('pkexec cp ' + MycroftDesktopFile + ' /usr/share/applications/')
            os.system('python3 ' + workingDirectory + '/Mycroft/mycroft-reborn.py &')
            # Inform the user by updating the button label
            builder.get_object("Mycroft").set_label(locale["RebornOSFIRE"]["ProgramsTab"]["AddonsTab"]["RemoveMycroft"])

    # Control Anbox
    def clickControlAnbox(self, button):
        os.system('pkexec bash ' + bashFile + ' InstallAnbox')

    # Send File with Wormhole
    def wormholeFile(self, menuitem):
        global filechosen
        filechosen = menuitem.get_file().get_path()
        os.system('pkexec bash ' + bashFile + ' SetupWormhole ' + filechosen)

    # Send Folder with Wormhole
    def wormholeFolder(self, menuitem):
        global filechosen
        filechosen = menuitem.get_file().get_path()
        print(filechosen)
        os.system('pkexec bash ' + bashFile + " SetupWormhole '" + filechosen + "'")

    # Receive File / Folder with Wormhole
    def wormholeReceive(self, pkgtxt):
        global enteredText
        enteredText = pkgtxt.get_text()
        os.system('pkexec bash ' + bashFile + ' ReceiveWormhole ' + enteredText)

################################################################################
############################### Seventh Tab ######################################
################################################################################

    # Open Pace
    def clickPacman(self, button):
        os.system('bash ' + bashFile + ' InstallTools pace ' + self.settings["terminal"])

    # Open Arch Kernel Manager
    def clickKernel(self, button):
        os.system('bash ' + bashFile + ' InstallTools pyakm-manager ' + self.settings["terminal"])

    # Open Stacer
    def clickStacer(self, button):
        os.system('bash ' + bashFile + ' InstallTools stacer ' + self.settings["terminal"])

    # Open Pamac
    def clickPamac(self, button):
        os.system('bash ' + bashFile + ' InstallTools pamac-manager ' + self.settings["terminal"])

################################################################################
############################### Drawing App Window #############################
################################################################################

builder = Gtk.Builder()
builder.add_from_file(gladeFile)
builder.connect_signals(Handler())

# =====================================
# View the file when the window pops up
# =====================================
with open(workingDirectory + '/Settings/lightdm.txt', 'r') as lightdmFile:
    Lines = lightdmFile.readlines()
    for line in Lines:
        builder.get_object("LightDMTestGreeterBox").append_text(line.strip())
        builder.get_object("LightDMUseGreeterBox").append_text(line.strip())
# =====================================

# =====================================
# View the file when the window pops up
# =====================================
with open(workingDirectory + '/Settings/sddm.txt', 'r') as sddmFile:
    Lines = sddmFile.readlines()
    for line in Lines:
        builder.get_object("SDDMTestThemeBox").append_text(line.strip())
        builder.get_object("SDDMUseThemeBox").append_text(line.strip())
# =====================================

# =====================================
# Set text through the use of keys from the JSON files used for translations
# =====================================
with open(localeDirectory + '/translations_' + os.getenv('LANG').split('_')[0] + '.json') as json_file:
    locale = json.load(json_file)

    # Fetch the main stack for the sidebar
    main_stack = builder.get_object("main_stack")

    # SETTINGS BUTTON
    builder.get_object("SettingsDialog").set_label(locale["RebornOSFIRE"]["Settings"]["SettingsDialog"])

    # REBORNOS CUSTOMIZATION MAIN TAB
    rebornos_customization_page = main_stack.get_child_by_name("rebornos_customization_page")
    main_stack.child_set_property(rebornos_customization_page, "title", locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["RebornOSCustomization"])
    # -----> Display Managers sub-Tab
    builder.get_object("DisplayManagers").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DisplayManagersTab"]["DisplayManagers"])
    builder.get_object("LightDM").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DisplayManagersTab"]["LightDMColumn"]["LightDM"])
    builder.get_object("LightDMdefault").set_label(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DisplayManagersTab"]["LightDMColumn"]["DefaultDM"])
    builder.get_object("LightDMUseGreeterText").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DisplayManagersTab"]["LightDMColumn"]["UseGreeter"])
    builder.get_object("LightDMTestGreeterText").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DisplayManagersTab"]["LightDMColumn"]["TestGreeter"])
    builder.get_object("SDDM").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DisplayManagersTab"]["SDDMColumn"]["SDDM"])
    builder.get_object("SDDMdefault").set_label(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DisplayManagersTab"]["SDDMColumn"]["DefaultDM"])
    builder.get_object("SDDMUseThemeText").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DisplayManagersTab"]["SDDMColumn"]["UseTheme"])
    builder.get_object("SDDMTestThemeText").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DisplayManagersTab"]["SDDMColumn"]["TestTheme"])
    # -----> Desktop Environments sub-Tab
    builder.get_object("DesktopEnvironments").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DesktopEnvironmentsTab"]["DesktopEnvironments"])
    builder.get_object("Budgie").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DesktopEnvironmentsTab"]["Budgie"])
    builder.get_object("Cinnamon").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DesktopEnvironmentsTab"]["Cinnamon"])
    builder.get_object("Deepin").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DesktopEnvironmentsTab"]["Deepin"])
    builder.get_object("Enlightenment").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DesktopEnvironmentsTab"]["Enlightenment"])
    builder.get_object("GNOME").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DesktopEnvironmentsTab"]["GNOME"])
    builder.get_object("i3").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DesktopEnvironmentsTab"]["i3"])
    builder.get_object("KDEplasma").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DesktopEnvironmentsTab"]["KDEplasma"])
    builder.get_object("LXQt").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DesktopEnvironmentsTab"]["LXQt"])
    builder.get_object("Mate").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DesktopEnvironmentsTab"]["Mate"])
    builder.get_object("OpenBox").set_text(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DesktopEnvironmentsTab"]["OpenBox"])
    builder.get_object("XFCE").set_label(locale["RebornOSFIRE"]["RebornOSCustomizationTab"]["DesktopEnvironmentsTab"]["XFCE"])

    # REBORNOS SYSTEM TASKS TAB
    system_tasks_page = main_stack.get_child_by_name("system_tasks_page")
    main_stack.child_set_property(system_tasks_page, "title", locale["RebornOSFIRE"]["SystemTasksTab"]["SystemTasks"])
    # -----> System Maintenance sub-tab
    builder.get_object("SystemMaintenanceTab").set_text(locale["RebornOSFIRE"]["SystemTasksTab"]["SystemMaintenanceTab"]["SystemMaintenance"])
    # Calculate the space that can be saved and add it on to the end of the text
    removeAll = locale["RebornOSFIRE"]["SystemTasksTab"]["SystemMaintenanceTab"]["RemoveAll"] + TotalStorage()
    builder.get_object("RemoveAll").set_text(removeAll)
    builder.get_object("RemoveAdvanced").set_text(locale["RebornOSFIRE"]["SystemTasksTab"]["SystemMaintenanceTab"]["RemoveAdvanced"])
    removeCache = locale["RebornOSFIRE"]["SystemTasksTab"]["SystemMaintenanceTab"]["CacheRemove"] + CacheStorage()
    builder.get_object("CacheRemove").set_text(removeCache)
    removeJournal = locale["RebornOSFIRE"]["SystemTasksTab"]["SystemMaintenanceTab"]["CleanJournal"] + JournalStorage()
    builder.get_object("CleanJournal").set_text(removeJournal)
    removePackages = locale["RebornOSFIRE"]["SystemTasksTab"]["SystemMaintenanceTab"]["RemoveUnnecessaryPrograms"] + PackageStorage()
    builder.get_object("RemoveUnnecessaryPrograms").set_text(removePackages)

    builder.get_object("RankMirrors").set_text(locale["RebornOSFIRE"]["SystemTasksTab"]["SystemMaintenanceTab"]["RankMirrors"])
    builder.get_object("goApply3").set_label(locale["RebornOSFIRE"]["SystemTasksTab"]["SystemMaintenanceTab"]["Apply"])
    # -----> Repair sub-tab
    builder.get_object("RepairTab").set_text(locale["RebornOSFIRE"]["SystemTasksTab"]["RepairTab"]["Repair"])
    builder.get_object("SaveRecover").set_text(locale["RebornOSFIRE"]["SystemTasksTab"]["RepairTab"]["SaveRecover"])
    builder.get_object("ReinstallGrub").set_text(locale["RebornOSFIRE"]["SystemTasksTab"]["RepairTab"]["ReinstallGrub"])
    builder.get_object("RebuildGrub").set_text(locale["RebornOSFIRE"]["SystemTasksTab"]["RepairTab"]["RebuildGrub"])
    builder.get_object("Downgrade").set_text(locale["RebornOSFIRE"]["SystemTasksTab"]["RepairTab"]["Downgrade"])
    builder.get_object("RemovePackage").set_text(locale["RebornOSFIRE"]["SystemTasksTab"]["RepairTab"]["RemovePackage"])
    builder.get_object("goApply1").set_label(locale["RebornOSFIRE"]["SystemTasksTab"]["RepairTab"]["Apply"])

    # REBORNOS PROGRAMS TAB
    programs_page = main_stack.get_child_by_name("programs_page")
    main_stack.child_set_property(programs_page, "title", locale["RebornOSFIRE"]["ProgramsTab"]["Programs"])
    # -----> Addons sub-tab
    builder.get_object("AddonsTab").set_label(locale["RebornOSFIRE"]["ProgramsTab"]["AddonsTab"]["Addons"])
    # Checks if Anbox is installed or not
    #   1) Stores output of shell command determining if anbox is installed as a snap already or not
    #   2) Determines the appropriate text to display for Anbox based on the result of step 1
    isAnboxInstalled = subprocess.check_output("snap list | grep 'anbox' | wc -l", shell=True)
    if isAnboxInstalled is True:
        builder.get_object("Anbox").set_label(locale["RebornOSFIRE"]["ProgramsTab"]["AddonsTab"]["RemoveAnbox"])
    else:
        builder.get_object("Anbox").set_label(locale["RebornOSFIRE"]["ProgramsTab"]["AddonsTab"]["InstallAnbox"])
    # Checks is Mycroft is installed or not
    #   1) Saves mycroft.desktop file location in a variable
    #   2) Saves mycroft-core directory location in a variable
    #   3) Enacts condition of 1 and 2 in order to determine the appropriate text to display for Mycroft
    mycroftFile= Path("/usr/share/applications/mycroft.desktop")
    userHome = subprocess.check_output("grep $(who | awk 'FNR == 1 {print $1}') /etc/passwd | rev | cut -f2 -d : | rev", shell=True)
    userHome = userHome.decode()
    mycroftDirectory = Path(userHome + "/mycroft-core")
    if mycroftFile.exists() or mycroftDirectory.exists():
        builder.get_object("Mycroft").set_label(locale["RebornOSFIRE"]["ProgramsTab"]["AddonsTab"]["RemoveMycroft"])
    else:
        builder.get_object("Mycroft").set_label(locale["RebornOSFIRE"]["ProgramsTab"]["AddonsTab"]["ControlMycroft"])
    # -----> Tools sub-tab
    builder.get_object("ToolsTab").set_label(locale["RebornOSFIRE"]["ProgramsTab"]["ToolsTab"]["Tools"])
    builder.get_object("PacmanSettings").set_label(locale["RebornOSFIRE"]["ProgramsTab"]["ToolsTab"]["PacmanSettings"])
    builder.get_object("ArchKernelManager").set_label(locale["RebornOSFIRE"]["ProgramsTab"]["ToolsTab"]["ArchKernelManager"])
    builder.get_object("Stacer").set_label(locale["RebornOSFIRE"]["ProgramsTab"]["ToolsTab"]["Stacer"])
    builder.get_object("Pamac").set_label(locale["RebornOSFIRE"]["ProgramsTab"]["ToolsTab"]["Pamac"])
    # -----> Wormhole sub-tab
    builder.get_object("WormholeTab").set_text(locale["RebornOSFIRE"]["ProgramsTab"]["WormholeTab"]["Wormhole"])
    builder.get_object("WhatIsWormhole").set_text(locale["RebornOSFIRE"]["ProgramsTab"]["WormholeTab"]["WhatIsWormhole"])
    builder.get_object("WormholeDescription").set_text(locale["RebornOSFIRE"]["ProgramsTab"]["WormholeTab"]["WormholeDescription"])
    builder.get_object("SelectFile").set_text(locale["RebornOSFIRE"]["ProgramsTab"]["WormholeTab"]["SelectFile"])
    builder.get_object("SelectFolder").set_text(locale["RebornOSFIRE"]["ProgramsTab"]["WormholeTab"]["SelectFolder"])
    builder.get_object("EnterCode").set_placeholder_text(locale["RebornOSFIRE"]["ProgramsTab"]["WormholeTab"]["EnterCode"])

    # REBORNOS ROLLBACK TAB
    rollback_page = main_stack.get_child_by_name("rollback_page")
    main_stack.child_set_property(rollback_page, "title", locale["RebornOSFIRE"]["RollbackTab"]["Rollback"])

    builder.get_object("RollbackSystem").set_text(locale["RebornOSFIRE"]["RollbackTab"]["RollbackSystem"])
    builder.get_object("RollbackUse").set_label(locale["RebornOSFIRE"]["RollbackTab"]["Rollback"])
    builder.get_object("UpgradeToCurrent").set_label(locale["RebornOSFIRE"]["RollbackTab"]["UpgradeToCurrent"])

    # Ensure calendar is set to the current date
    builder.get_object("RollbackCalendar").set_property("day", date.today().day)
    builder.get_object("RollbackCalendar").set_property("month", date.today().month - 1)
    builder.get_object("RollbackCalendar").set_property("year", date.today().year)
# =====================================

window2 = builder.get_object("RebornOSFIRE")
window2.show_all()

Gtk.main()

Notify.uninit()
