MRTestRepo/PepProTools/pepu.py

691 lines
21 KiB
Python
Executable File

#!/usr/bin/env python3
__author__ = "PepDebian"
__copyright__ = "Copyright (C) 2022 PepDebian"
__license__ = "GPL"
__version__ = "3.0 or greater"
import tkinter as tk
import subprocess
import tkinter
import ttkbootstrap as ttk
import filecmp
import os
import shutil
import time
import sqlite3
import datetime
from crontab import CronTab
from git import Repo
from ttkbootstrap.scrolled import ScrolledText
from ttkbootstrap.constants import *
from tkinter import Frame
from threading import Thread
##setup the window
pwin = ttk.Window(themename="darkly")
pwin.title('Peppermint Update Manager')
pwin.tk.call('wm', 'iconphoto', pwin._w,
tk.PhotoImage(
file='/usr/share/pixmaps/peppermint-old.png'))
pwin['bg'] = '#000000'
window_height = 630
window_width = 750
##set the database connection string
dcon = sqlite3.connect('/opt/pypep/dbpep/welval.db')
pcur = dcon.cursor()
#Create the update table
pcur.execute(""" CREATE TABLE IF NOT EXISTS upsched (id integer PRIMARY KEY AUTOINCREMENT, dname text, cronnum int, hr int, min int);""")
## The Functions
def center_screen():
""" gets the coordinates of the center of the screen. """
global screen_height, screen_width, x_cordinate, y_cordinate
screen_width = pwin.winfo_screenwidth()
screen_height = pwin.winfo_screenheight()
# Coordinates of the upper left corner of the window
# to make the window appear in the center
x_cordinate = int((screen_width/2) - (window_width/2))
y_cordinate = int((screen_height/2) - (window_height/2))
pwin.geometry("{}x{}+{}+{}".format(window_width,
window_height, x_cordinate,
y_cordinate))
def drepo():
"""Delete the temp repo files."""
fld = '/opt/tmprpo/'
for filename in os.listdir(fld):
fp = os.path.join(fld, filename)
try:
if os.path.isfile(fp) or os.path.islink(fp):
os.unlink(fp)
elif os.path.isdir(fp):
shutil.rmtree(fld)
except Exception as e:
print('Failed to delete %s. Reason: %s' % (fp, e))
def cbclone():
"""Clones the Production Tools Repo locally"""
repo_url = 'https://codeberg.org/Peppermint_OS/PepProTools.git'
repo_path = '/opt/tmprpo/'
if os.path.exists(repo_path):
shutil.rmtree(repo_path)
else:
os.makedirs(repo_path)
Repo.clone_from(repo_url, repo_path)
def checkfiles():
"""Compare the repo files downloaded with what is in opt and detemrine if an update is needed"""
b = '/opt/pypep/'
a = '/opt/tmprpo/'
comp = filecmp.dircmp(a, b)
common = sorted(comp.common)
left = sorted(comp.left_list)
right = sorted(comp.right_list)
if left != common or right != common:
file_names = os.listdir(a)
for file_name in file_names:
if file_name.endswith(".git"):
pass
else:
shutil.copy(os.path.join(a, file_name), b)
else:
pass
def updtpeptools():
"""brings all the update tool functions together"""
terminalstuff.delete(1.0,END)
pwin.update()
msg1='''
Checking Codeberg for updates'''
terminalstuff.insert('end', msg1)
pwin.update()
cbclone()
msg2='''
Applying updates'''
terminalstuff.insert('end', msg2)
pwin.update()
checkfiles()
msg3='''
Cleaning up....'''
terminalstuff.insert('end', msg3)
pwin.update()
drepo()
message ='''
Your Peppermint Tools have been updated!'''
terminalstuff.insert('end', message)
pwin.update()
def pu(cmd, terminal):
"""set up the pipe process."""
#set thecompleted message
pepipe = subprocess.Popen(cmd, stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
bufsize=1,
universal_newlines=True,
shell=True)
pepipe.poll()
while True:
line = pepipe.stdout.readline()
terminal.insert(tk.END, line)
terminal.see(tk.END)
if not line and pepipe.poll is not None:
break
commsg='''Completed!'''
terminalstuff.insert('end', commsg)
def peppersys():
""" This will apt command and send the results to the terminal textbox """
sysu = "apt update && apt upgrade -y"
pepper = Thread(target=lambda: pu(sysu, terminalstuff))
pepper.start()
terminalstuff.delete(1.0,END)
def ldsettings():
"""Preset the update options based on what is stored in the database"""
##set the connector
dbst = sqlite3.connect('/opt/pypep/dbpep/welval.db')
mvar ="Mon"
tuvar ="Tue"
wvar ="Wed"
tvar ="Thu"
fvar ="Fri"
savar ="Sat"
suvar ="Sun"
##set the queries
cbval= """ SELECT COUNT(*) FROM upsched WHERE dname = ?;"""
hval= """ SELECT hr FROM upsched WHERE hr IS NOT NULL;"""
hcval= """ SELECT COUNT(*) FROM upsched WHERE hr IS NOT NULL;"""
mval= """ SELECT min FROM upsched WHERE min IS NOT NULL;"""
mcval= """ SELECT COUNT(*) FROM upsched WHERE min IS NOT NULL;"""
##set the cursor to be used for execution
dcur = dbst.cursor()
##Start the hr call
dcur.execute(hcval)
hrc = dcur.fetchone()
if int(hrc[0])>0:
#If there is a hour value in the databes set the texbox
#widget to that value.
dcur.execute(hval)
hsel = dcur.fetchone()
txtopthour.insert(0,hsel)
else:
#if there is no value print this message and pass.
print ('No hour value is there')
pass
##Start the minute call
dcur.execute(mcval)
minc = dcur.fetchone()
if int(minc[0])>0:
#If there is a minute value in the databes set the texbox
#widget to that value.
dcur.execute(mval)
msel = dcur.fetchone()
txtoptmin.insert(0,msel)
else:
#if there is no value print this message and pass.
print ('No minute value is there')
pass
##Start text box settings...##
##Monday
dcur.execute (cbval,(mvar,))
mr = dcur.fetchone()
if int(mr[0]) > 0:
#if the cbval is in the DB then print and set the checkbutton
#value
cbm_v.set(1)
print ("Mon is there")
else:
#If the cbval is 0 then print this message
print ('Nothing There')
pass
#Tue##
dcur.execute (cbval,(tuvar,))
tur = dcur.fetchone()
if int(tur[0]) > 0:
cbtu_v.set(1)
print ("Tue is there")
else:
print ('Nothing There')
pass
##Wed##
dcur.execute (cbval,(wvar,))
wr = dcur.fetchone()
if int(wr[0]) > 0:
cbw_v.set(1)
print ("Wed is there")
else:
print ('Nothing There')
pass
##Thu##
dcur.execute (cbval,(tvar,))
tr = dcur.fetchone()
if int(tr[0]) > 0:
cbt_v.set(1)
print ("Thu is there")
else:
print ('Nothing There')
pass
##Fri##
dcur.execute (cbval,(fvar,))
fr = dcur.fetchone()
if int(fr[0]) > 0:
cbf_v.set(1)
print ("Fri is there")
else:
print ('Nothing There')
pass
##Sat##
dcur.execute (cbval,(savar,))
sar = dcur.fetchone()
if int(sar[0]) > 0:
cbsa_v.set(1)
print ("Sat is there")
else:
print ('Nothing There')
pass
##Sun##
dcur.execute (cbval,(suvar,))
sur = dcur.fetchone()
if int(sur[0]) > 0:
cbsu_v.set(1)
print ("Sun is there")
else:
print ('Nothing There')
pass
def pcron():
"""This will set ccron table schedule to run updates"""
cron = CronTab(user='root')
# get the value that is entered in the hour text box
# it must be with 0 to 24 other wise it is out of range
# then see if the hour is already in the DB if it is
# delete it and add in the new value from the text box
# else its a new record and you just need to add it
##set the connector
db = sqlite3.connect('/opt/pypep/dbpep/welval.db')
#set the cursor
dbcur = db.cursor()
##This section will save the hour values entered in the database
hrtx = txtopthour.get()
if len(hrtx) == 0:
#If nothing was entered then print the message and pass the if
print ('nothing entered')
pass
else:
#if there is a value then delete it first then add the record
#other wise just add the record.
hra = int(hrtx)
if 0 <= hra <=24:
hval = """ SELECT COUNT(*) FROM upsched WHERE hr IS NOT NULL; """
hdel = """ DELETE FROM upsched WHERE hr IS NOT NULL; """
hrinsrt = """ INSERT INTO upsched (hr) VALUES (?); """
harg = hra
dbcur.execute(hval)
crresult = dbcur.fetchone()
if int(crresult[0]) > 0:
dbcur.execute(hdel)
db.commit()
dbcur.execute(hrinsrt,(harg,))
db.commit()
print(hra)
else:
dbcur.execute(hrinsrt, (harg,))
db.commit()
else:
print ('out of range')
##Same process for the Minute its a repeate as above but for the
##Minute text widget
mitx = txtoptmin.get()
if len(mitx) == 0:
print ('nothing entered')
pass
else:
mia = int(mitx)
if 0 <= mia <=24:
mval = """ SELECT COUNT(*) FROM upsched WHERE min IS NOT NULL; """
mdel = """ DELETE FROM upsched WHERE min IS NOT NULL; """
miinsrt = """ INSERT INTO upsched (min) VALUES (?); """
marg = mia
dbcur.execute(mval)
crresult = dbcur.fetchone()
if int(crresult[0]) > 0:
dbcur.execute(mdel)
db.commit()
dbcur.execute(miinsrt,(marg,))
db.commit()
print(mia)
else:
dbcur.execute(miinsrt, (marg,))
db.commit()
else:
print ('out of range')
# these are the days of the week checkbuttons if they are on or
# off do something
#var the message to print in terminal
alrdy = "There is already a value for that day,"
#set the variables used for the SQL queries
mvar ="Mon"
tuvar ="Tue"
wvar ="Wed"
tvar ="Thu"
fvar ="Fri"
savar ="Sat"
suvar ="Sun"
#set the queries
cval= """ SELECT COUNT(*) FROM upsched WHERE dname = ?;"""
dinsrt = """ INSERT INTO upsched(dname) VALUES (?);"""
drmv = """ DELETE FROM upsched WHERE dname = ?;"""
if cbm_v.get() == 1:
#run the query withthe variable
dbcur.execute (cval,(mvar,))
#get the result
crresult = dbcur.fetchone()
if int(crresult[0]) > 0:
#if the value is in the DB then print
print (alrdy, "Mon")
else:
#if it is not in the DB then add it
dbcur.execute(dinsrt,(mvar,))
db.commit()
print ('Mon Added to Database')
#Create the new job
jobm = cron.new(command='/bin/sh opt/pypep/pepwork.sh', comment='Monday')
#Set the value to what is in the hour textbox
jobm.hour.on(hra)
#Set the value to what is in the minute textbox
jobm.minute.on(mia)
#set the day of the week
jobm.dow.on('1')
#Write the job to the crontab
cron.write()
#Show the job was witten
print('wrote cron')
#list the jobs in the terminal
for jobm in cron:
print (jobm)
#this is the finish monday function
print ('mon is on')
else:
##If unchecked Remove the current day value
if cbm_v.get() == 0:
dbcur.execute (cval,(mvar,))
mdelresult = dbcur.fetchone()
if int(mdelresult[0]) > 0:
#run the delete query
dbcur.execute(drmv,(mvar,))
#commit the change to the database
db.commit()
#set what job to find in the crontab
jobm = cron.find_comment('Monday')
#Clear and write the contab
cron.remove(jobm)
cron.write()
#print that the cron job was deleted
print ('Mon Cron Deleted')
#print the Record was deleted from the Databaes
print ('Mon was deleted from db becuase the cb is off')
else:
#Print nothing deleted if nothing was found
print ('nothing to delete')
#pring that that the check box is off.
print ('mon is off')
if cbtu_v.get() == 1:
dbcur.execute (cval,(tuvar,))
crresult = dbcur.fetchone()
if int(crresult[0]) > 0:
print (alrdy, "Tue")
else:
dbcur.execute(dinsrt,(tuvar,))
db.commit()
print ('Tue Added to Database')
jobtu = cron.new(command='/bin/sh opt/pypep/pepwork.sh', comment='Tuesday')
jobtu.hour.on(hra)
jobtu.minute.on(mia)
jobtu.dow.on(2)
cron.write()
for jobtu in cron:
print (jobtu)
print('wrote cron')
print ('tue is on')
else:
if cbtu_v.get() == 0:
dbcur.execute (cval,(tuvar,))
tudelresult = dbcur.fetchone()
if int(tudelresult[0]) > 0:
dbcur.execute(drmv,(tuvar,))
db.commit()
jobtu = cron.find_comment('Tuesday')
cron.remove(jobtu)
cron.write()
print ('Tue Cron Deleted')
print ('Tue was deleted from db becuase the cb is off')
else:
print ('nothing to delete')
print ('tue is off')
if cbw_v.get() == 1:
dbcur.execute (cval,(wvar,))
crresult = dbcur.fetchone()
if int(crresult[0]) > 0:
print (alrdy, "Wed")
else:
dbcur.execute(dinsrt,(wvar,))
db.commit()
print ('Wed Added to Database')
jobw = cron.new(command='/bin/sh opt/pypep/pepwork.sh', comment='Wednesday')
jobw.hour.on(hra)
jobw.minute.on(mia)
jobw.dow.on(3)
cron.write()
print('wrote cron')
print ('wed is on')
else:
if cbw_v.get() == 0:
dbcur.execute (cval,(wvar,))
wdelresult = dbcur.fetchone()
if int(wdelresult[0]) > 0:
dbcur.execute(drmv,(wvar,))
db.commit()
jobw = cron.find_comment('Wednesday')
cron.remove(jobw)
cron.write()
print ('Wed Cron Deleted')
print ('Wed was deleted from db becuase the cb is off')
else:
print ('nothing to delete')
print ('wed is off')
if cbt_v.get() == 1:
dbcur.execute (cval,(tvar,))
crresult = dbcur.fetchone()
if int(crresult[0]) > 0:
print (alrdy, "Thu")
else:
dbcur.execute(dinsrt,(tvar,))
db.commit()
print ('Thu Added to Database')
jobt = cron.new(command='/bin/sh opt/pypep/pepwork.sh', comment='Thursday')
jobt.hour.on(hra)
jobt.minute.on(mia)
jobt.dow.on(4)
cron.write()
print('wrote cron')
print ('thu is on')
else:
if cbt_v.get() == 0:
dbcur.execute (cval,(tvar,))
tdelresult = dbcur.fetchone()
if int(tdelresult[0]) > 0:
dbcur.execute(drmv,(tvar,))
db.commit()
jobt = cron.find_comment('Thursday')
cron.remove(jobt)
cron.write()
print ('Thu Cron Deleted')
print ('Thu was deleted from db becuase the cb is off')
else:
print ('nothing to delete')
print ('thu is off')
if cbf_v.get() == 1:
dbcur.execute (cval,(fvar,))
crresult = dbcur.fetchone()
if int(crresult[0]) > 0:
print (alrdy, "Fri")
else:
dbcur.execute(dinsrt,(fvar,))
db.commit()
print ('Fri Added to Database')
jobf = cron.new(command='/bin/sh opt/pypep/pepwork.sh', comment='Friday')
jobf.hour.on(hra)
jobf.minute.on(mia)
jobf.dow.on(5)
cron.write()
print('wrote cron')
print ('fri is on')
else:
if cbf_v.get() == 0:
dbcur.execute (cval,(fvar,))
fdelresult = dbcur.fetchone()
if int(fdelresult[0]) > 0:
dbcur.execute(drmv,(fvar,))
db.commit()
jobf = cron.find_comment('Friday')
cron.remove(jobf)
cron.write()
print ('Fri Cron Deleted')
print ('Fri was deleted from db becuase the cb is off')
else:
print ('nothing to delete')
print ('fri is off')
if cbsa_v.get() == 1:
dbcur.execute (cval,(savar,))
crresult = dbcur.fetchone()
if int(crresult[0]) > 0:
print (alrdy, "Sat")
else:
dbcur.execute(dinsrt,(savar,))
db.commit()
print ('Sat Added to Database')
jobsa = cron.new(command='/bin/sh opt/pypep/pepwork.sh', comment='Saturday')
jobsa.hour.on(hra)
jobsa.minute.on(mia)
jobsa.dow.on(6)
cron.write()
print('wrote cron')
print ('sat is on')
else:
if cbsa_v.get() == 0:
dbcur.execute (cval,(savar,))
sadelresult = dbcur.fetchone()
if int(sadelresult[0]) > 0:
dbcur.execute(drmv,(savar,))
db.commit()
jobsa = cron.find_comment('Saturday')
cron.remove(jobsa)
cron.write()
print ('Sat Cron Deleted')
print ('Sat was deleted from db becuase the cb is off')
else:
print ('nothing to delete')
print ('sat is off')
if cbsu_v.get() == 1:
dbcur.execute (cval,(suvar,))
crresult = dbcur.fetchone()
if int(crresult[0]) > 0:
print (alrdy, "Sun")
else:
dbcur.execute(dinsrt,(suvar,))
db.commit()
print ('Sun Added to Database')
jobsu = cron.new(command='/bin/sh opt/pypep/pepwork.sh', comment='Sunday')
jobsu.hour.on(hra)
jobsu.minute.on(mia)
jobsu.dow.on(0)
cron.write()
for job in cron:
print (job)
print('wrote cron')
print ('sun is on')
else:
if cbsu_v.get() == 0:
dbcur.execute (cval,(suvar,))
sudelresult = dbcur.fetchone()
if int(sudelresult[0]) > 0:
dbcur.execute(drmv,(suvar,))
db.commit()
jobsu = cron.find_comment('Sunday')
cron.remove(jobsu)
cron.write()
print ('Sun Cron Deleted')
print ('Sun was deleted from db because the cb is off')
else:
print ('nothing to delete')
print ('sun is off')
pwin.destroy()
#notebook stuff
pnb = ttk.Notebook(pwin, bootstyle="danger")
pnb.pack(pady=10, expand=True)
fnb1 = ttk.Frame (pnb, width=400, height=400)
fnb2 = ttk.Frame (pnb, width=400, height=400)
fnb1.pack(fill='both', expand=True)
fnb2.pack(fill='both', expand=True)
pnb.add(fnb1, text='Update Manager')
pnb.add(fnb2, text='Options')
# frames to use separate parts of the window
fbset0 = Frame (fnb1)
fbset0.pack(side="top")
fbset1 = Frame (fnb1)
fbset1.pack(side="top")
fbset3 = Frame (fnb1)
fbset3.pack(side="top")
fbset2 = Frame (fnb1)
fbset2.pack(side="top")
fbset4 = Frame (fnb1)
fbset4.pack(side="top")
fterm = Frame (fnb1)
fterm.pack(side="top", fill="both", expand = True)
#These lables provide space in betweenthe buttons
#Using pack on the Update manager tab
lbltitle = ttk.Label(fbset0)
lbltitle.pack()
lbltitle = ttk.Label(fbset3)
lbltitle.pack()
lbltitle = ttk.Label(fbset4)
lbltitle.pack()
#Holds the terminal output
terminalstuff = ScrolledText(fterm, padding=5, bootstyle="dark")
terminalstuff.pack(fill="both", expand = True)
## The things that are used on the Update Manager Tab
sysupdtbtn = ttk.Button(fbset1, text="System Updates", width=20, cursor="hand2", bootstyle="light-outline", command =peppersys)
sysupdtbtn.pack(side = "left")
ptupdtbtn = ttk.Button(fbset1, text="Update Pep Tools", width=20, cursor="hand2", bootstyle="light-outline", command=updtpeptools)
ptupdtbtn.pack(side = "left")
lblumsg = ttk.Label(fbset2, text="Use the buttons to update your tools or system", bootstyle="inverse-light")
lblumsg.pack()
## the things that are used on the Options tab
##The title of the Peppermint Tools Section
lblopttitle = ttk.Label(fnb2, text="Set a schedule for Peppermint tools", bootstyle="inverse-light")
lblopttitle.place(x=10, y=15)
##First one below the Peppermint tools title
sepoptlt = ttk.Separator(fnb2, bootstyle="danger", orient=HORIZONTAL)
sepoptlt.place(x=10, y=40, relwidth=1)
##Second one below the System Updates
sepopbtm = ttk.Separator(fnb2, bootstyle="danger", orient=HORIZONTAL)
sepopbtm.place(x=10, y=140, relwidth=1)
##The last one right above the information
sepopend = ttk.Separator(fnb2, bootstyle="danger", orient=HORIZONTAL)
sepopend.place(x=10, y=240, relwidth=1)
cbm_v = tkinter.IntVar()
cbm = ttk.Checkbutton(fnb2, text = "Mon", variable = cbm_v, bootstyle="success-round-toggle")
cbm.place(x=10, y=180)
cbtu_v = tkinter.IntVar()
cbtu = ttk.Checkbutton(fnb2, text = "Tue", variable = cbtu_v, bootstyle="success-round-toggle")
cbtu.place(x=80, y=180)
cbw_v = tkinter.IntVar()
cbw = ttk.Checkbutton(fnb2, text = "Wed", variable = cbw_v, bootstyle="success-round-toggle")
cbw.place(x=160, y=180)
cbt_v = tkinter.IntVar()
cbt = ttk.Checkbutton(fnb2, text = "Thu", variable = cbt_v, bootstyle="success-round-toggle")
cbt.place(x=240, y=180)
cbf_v = tkinter.IntVar()
cbf = ttk.Checkbutton(fnb2, text = "Fri", variable = cbf_v, bootstyle="success-round-toggle")
cbf.place(x=10, y=210)
cbsa_v = tkinter.IntVar()
cbsa = ttk.Checkbutton(fnb2, text = "Sat", variable = cbsa_v, bootstyle="success-round-toggle")
cbsa.place(x=80, y=210)
cbsu_v = tkinter.IntVar()
cbsu = ttk.Checkbutton(fnb2, text = "Sun", variable = cbsu_v, bootstyle="success-round-toggle")
cbsu.place(x=160, y=210)
##lets the user know the schedule will start from the selected date
lbloptdys = ttk.Label(fnb2, text="Select the days you want")
lbloptdys.place(x=10, y=150)
lblopttime = ttk.Label(fnb2, text="Select the time you want")
lblopttime.place(x=10, y=50)
lblopttimehr = ttk.Label(fnb2, text="hr")
lblopttimehr.place(x=17, y=80)
lblopttimemin = ttk.Label(fnb2, text="min")
lblopttimemin.place(x=66, y=80)
txtopthour = ttk.Entry(fnb2, bootstyle="danger", width=2)
txtopthour.place(x=10, y=100)
lblopttimecl = ttk.Label(fnb2, text=":")
lblopttimecl.place(x=50, y=105)
txtoptmin = ttk.Entry(fnb2, bootstyle="danger", width=2)
txtoptmin.place(x=66, y=100)
##this is the information section explaining what this application does.
##The frame that holds the message
instfr = ttk.Labelframe(fnb2, bootstyle="danger", text='Information')
instfr.place(x=10, y=270)
##The message
lblinstpt = ttk.Label(instfr, text="When you set a schedule for the Peppermint tools, the updater will check the git repos for any new updates that may be available and install them. Addtionally System Updates will check the Debian or Devuan repos depending on what spin of Peppermint you are running ", wraplength=600)
lblinstpt.pack(side="top", pady=5, padx=5)
btnpt = ttk.Button(fnb2, text="Save & Exit", cursor="hand2", bootstyle="light-outline", command=pcron)
btnpt.place(x=500, y=500)
#close db Connection
pcur.close
# call Center screen
center_screen()
ldsettings()
pwin.mainloop()