Skip to content

Demo Script Select and Install Applications

Bart Reardon edited this page Jan 26, 2022 · 1 revision

This is a demonstration script written in python that that highlights a number of Dialogs abilities:

  • Using SF Symbols as an icon with custom colours
  • Requesting the user for input via a number of checkboxes
  • Updating the message area with progress text and status provided by emoji using a command file
  • incrementing a progress bar
  • disabling the default button until the process is complete
  • blurring the display behind the dialog, preventing user input into other applications

There are likely a number of optimisations that could be made if this were to be used as a basis for a production workflow.

How it works

The script keep track of an array of items to install and the command used to trigger the install and uses this array to present a list of checkboxes. Based on what was selected, another array is created for the presentation. As each item is processed the presentation array is updated with the current state and then sent to the command file which dialog uses to update its display. The progress bar is then incremented

  • No actual processing is taking place in this script. The code is written to give the impression that activity is taking place for demonstration purposes

Screen capture of what the process generated by this script looks like

Screen.Recording.2022-01-23.at.3.34.25.pm-SD.480p.mov

Select and Install Applications script

#!/usr/bin/python3

import time
import os
import subprocess
import json

# [appname, install_trigger]
app_array = [ 
	["Firefox","jamf policy -event FIREFOX"],
	["Microsoft Edge", "installomator.sh microsoftedge"],
	["Google Chrome", "installomator.sh googlechrome"],
	["Adobe Photoshop", "jamf policy -event PHOTOSHOP"],
	["Some Other Stuff", "jamf policy -event OTHERSTUFF"],
	["Some More Stuff", "jamf policy -event MORESTUFF"]
	]

dialogApp = "/usr/local/bin/dialog"	

progress = 0
progress_steps = 100
progress_per_step = 1

# build string array for dialog to display
app_list = []
for app_name in app_array:
	app_list.append(["⬜️",app_name[0],app_name[1]])


def writeDialogCommands(command):
	file = open("/var/tmp/dialog.log", "a")
	file.writelines("{}\n".format(command))
	file.close()
	

def updateDialogCommands(array, steps):
	string = "__Installing Software__\\n\\n"
	
	for item in array:
		string = string + "{} - {}  \\n".format(item[0],item[1])
		
	writeDialogCommands("message: {}".format(string))
	if steps > 0:
		writeDialogCommands("progress: {}".format(steps))
		

# app string
app_string = ""
for app_name in app_array:
	app_string = "{} --checkbox '{}'".format(app_string, app_name[0])


# Run dialogApp and return the results as json
dialog_cmd = "{} --title 'Software Installation' \
--message 'Select Software to install:' \
--icon SF=desktopcomputer.and.arrow.down,colour1=#3596f2,colour2=#11589b \
--button1text Install \
-2 -s --height 420 --json {} ".format(dialogApp, app_string)
			
result = subprocess.Popen(dialog_cmd, shell=True, stdout=subprocess.PIPE)
text = result.communicate()[0]   # contents of stdout
#print(text)

result_json = json.loads(text)

print(result_json)

for key in result_json:
	print(key, ":", result_json[key])
	for i, app_name in enumerate(app_list):
		#print(i)
		if key == app_name[1] and result_json[key] == False:
			print("deleting {} at index {}".format(key, i))
			app_list.pop(i)

print(app_list)

# re-calc steps per item
progress_per_step = progress_steps/len(app_list)

os.system("{} --title 'Software Installation' \
				--message 'Software Install is about to start' \
				--button1text 'Please Wait' \
				--icon SF=desktopcomputer.and.arrow.down,colour1=#3596f2,colour2=#11589b \
				--blurscreen \
				--progress {} \
				-s --height 420 \
				&".format(dialogApp, progress_steps))

# give time for Dialog to launch
time.sleep(0.5)
writeDialogCommands("button1: disable")

time.sleep(2)
writeDialogCommands("title: Software Installation")
writeDialogCommands("button1text: Please Wait")
writeDialogCommands("progress: 0")

#Process the list
for app in app_list:
	progress = progress + progress_per_step
	writeDialogCommands("progressText: Installing {}...".format(app[1]))
	app[0] = "⏳"
	
	updateDialogCommands(app_list, 0)
	
	##### This is where you'd perform the install
	
	# Pretend install happening 
	print("Right now we would be running this command\n : {}".format(app[2]))
	time.sleep(1) 
	writeDialogCommands("progress: increment")
	time.sleep(1)
	writeDialogCommands("progress: increment")
	time.sleep(1)
	writeDialogCommands("progress: increment")
	time.sleep(1)
	writeDialogCommands("progress: increment")
	
	app[0] = "✅"
	
	updateDialogCommands(app_list, progress)
	writeDialogCommands("progressText: Installing {}...".format(app[1]))
	time.sleep(1)

writeDialogCommands("icon: SF=checkmark.shield.fill,colour1=#27db2d,colour2=#1b911f")
writeDialogCommands("progressText: Complete")		
writeDialogCommands("button1text: Done")
writeDialogCommands("button1: enable")
Clone this wiki locally