Skip to content

Instantly share code, notes, and snippets.

@weswhet
Created January 10, 2017 16:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save weswhet/9f87c1bbfac266653b42edff90bea0d4 to your computer and use it in GitHub Desktop.
Save weswhet/9f87c1bbfac266653b42edff90bea0d4 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
import sys
import os
import subprocess
import datetime
from Foundation import NSDate, NSMetadataQuery, NSPredicate, NSRunLoop
from Foundation import CFPreferencesAppSynchronize
from Foundation import CFPreferencesCopyAppValue
from Foundation import CFPreferencesCopyKeyList
from Foundation import CFPreferencesSetValue
from Foundation import kCFPreferencesAnyUser
from Foundation import kCFPreferencesCurrentUser
from Foundation import kCFPreferencesCurrentHost
sys.path.append('/usr/local/munki/munkilib')
import FoundationPlist # nopep8
import munkicommon # nopep8
def current_user():
return munkicommon.getconsoleuser()
def get_available_updates():
'''Returns the number of available updates from the munki prefs'''
try:
puc = int(munkicommon.pref('PendingUpdateCount'))
if puc and puc > 0:
return puc
return 0
except ValueError:
munkicommon.display_warning(
'PendingUpdateCount is not an integer: {}.'.format(
munkicommon.pref('DaysBetweenNotifications')))
return 0
def mscalert_running():
process_list = subprocess.check_output(['ps', 'auxwww'])
if 'MSCalert' in process_list:
return True
else:
return False
def alertUserOfUpdates(updates, force=False):
"""Notify the logged-in user of available updates.
Args:
force: bool, default False, forcefully notify user regardless
of LastNotifiedDate.
Returns:
Boolean. True if the user was notified, False otherwise.
"""
# called when options.auto == True
# someone is logged in, and we have updates.
# if we haven't notified in a while, notify:
user_was_notified = False
lastNotifiedString = munkicommon.pref('LastAlertDate')
try:
daysBetweenNotifications = int(
munkicommon.pref('HoursBetweenAlerts'))
except TypeError:
munkicommon.display_warning(
'HoursBetweenAlerts is not an integer: %s'
% munkicommon.pref('HoursBetweenAlerts'))
# continue with the default HoursBetweenAlerts
daysBetweenNotifications = 4
munkicommon.set_pref('HoursBetweenAlerts', daysBetweenNotifications)
now = NSDate.new()
nextNotifyDate = now
if lastNotifiedString:
lastNotifiedDate = NSDate.dateWithString_(lastNotifiedString)
interval = daysBetweenNotifications * (60 * 60)
if daysBetweenNotifications > 0:
# we make this adjustment so a 'daily' notification
# doesn't require 24 hours to elapse
# subtract 30 minutes
interval = interval - (30 * 60)
nextNotifyDate = lastNotifiedDate.dateByAddingTimeInterval_(interval)
if force or now.timeIntervalSinceDate_(nextNotifyDate) >= 0:
# record current notification date
munkicommon.set_pref('LastAlertDate', now)
munkicommon.display_debug1('Alerting user of available updates.')
munkicommon.display_debug1('LastAlertDate was {}'.format(
lastNotifiedString))
# notify user of available updates using LaunchAgent to start
# Managed Software Update.app in the user context.
if updates == 1:
plural = "update"
else:
plural = "updates"
send_alert(current_user(), updates, plural)
user_was_notified = True
return user_was_notified
def send_alert(current_user, updates, plural):
DEVNULL = open(os.devnull, 'wb')
munkicommon.display_debug1('Sending Notification Center Alert...')
apps_util = "/Applications/Utilities/"
alert_app = "MSCalert.app/Contents/MacOS/MSCalert"
alert_path = os.path.join(apps_util, alert_app)
cmd = ['su', '-l', current_user, '-c', '{0} -t "Managed Software Center" \
-a munki://updates -n "You have {1} available {2}." -b "Open"'.format(
alert_path, updates, plural)]
subprocess.call(cmd, stdout=DEVNULL, stderr=subprocess.STDOUT, close_fds=True)
def main():
if mscalert_running():
kill_cmd = ['/usr/bin/killall', 'MSCalert']
subprocess.call(kill_cmd)
if len(sys.argv) > 1:
if sys.argv[1] != 'auto':
print 'Not Auto Run: Skipping!'
exit(0)
current_day = datetime.date.today().strftime("%a")
if current_day == "Wed":
print "It's Wednesday! We do full MSC pop ups today..."
exit(0)
available_updates = get_available_updates()
if available_updates == 0:
exit(0)
alertUserOfUpdates(available_updates)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment