mirror of
https://github.com/munki/munki.git
synced 2026-04-20 03:30:42 -05:00
Add doc strings to all functions and methods
This commit is contained in:
@@ -28,6 +28,7 @@ class AlertController(NSObject):
|
||||
self.window = the_window
|
||||
|
||||
def forcedLogoutWarning(self, notification_obj):
|
||||
'''Display a forced logout warning'''
|
||||
NSApp.activateIgnoringOtherApps_(True)
|
||||
info = notification_obj.userInfo()
|
||||
moreText = NSLocalizedString(
|
||||
@@ -95,6 +96,7 @@ class AlertController(NSObject):
|
||||
@AppHelper.endSheetMethod
|
||||
def forceLogoutWarningDidEnd_returnCode_contextInfo_(
|
||||
self, alert, returncode, contextinfo):
|
||||
'''Called when the forced logout warning alert ends'''
|
||||
self._currentAlert = None
|
||||
btn_pressed = self._force_warning_btns.get(returncode)
|
||||
if btn_pressed == self._force_warning_logout_btn:
|
||||
@@ -104,6 +106,7 @@ class AlertController(NSObject):
|
||||
msulog.log("user", "dismissed_forced_logout_warning")
|
||||
|
||||
def alertToExtraUpdates(self):
|
||||
'''Notify user of additional pending updates'''
|
||||
alert = NSAlert.alertWithMessageText_defaultButton_alternateButton_otherButton_informativeTextWithFormat_(
|
||||
NSLocalizedString(u"Additional Pending Updates", u'AdditionalPendingUpdatesText'),
|
||||
NSLocalizedString(u"OK", u'OKButtonText'),
|
||||
@@ -119,9 +122,11 @@ class AlertController(NSObject):
|
||||
@AppHelper.endSheetMethod
|
||||
def extraUpdatesAlertDidEnd_returnCode_contextInfo_(
|
||||
self, alert, returncode, contextinfo):
|
||||
'''Called when the extra updates alert ends'''
|
||||
self._currentAlert = None
|
||||
|
||||
def confirmUpdatesAndInstall(self):
|
||||
'''Make sure it's OK to proceed with installing if logout or restart is required'''
|
||||
if self.alertedToMultipleUsers():
|
||||
return
|
||||
elif MunkiItems.updatesRequireRestart():
|
||||
@@ -159,6 +164,7 @@ class AlertController(NSObject):
|
||||
@AppHelper.endSheetMethod
|
||||
def logoutAlertDidEnd_returnCode_contextInfo_(
|
||||
self, alert, returncode, contextinfo):
|
||||
'''Called when logout alert ends'''
|
||||
self._currentAlert = None
|
||||
if returncode == NSAlertDefaultReturn:
|
||||
if self.alertedToFirmwareUpdatesAndCancelled():
|
||||
@@ -201,6 +207,7 @@ class AlertController(NSObject):
|
||||
@AppHelper.endSheetMethod
|
||||
def multipleUserAlertDidEnd_returnCode_contextInfo_(
|
||||
self, alert, returncode, contextinfo):
|
||||
'''Called when multiple users alert ends'''
|
||||
self._currentAlert = None
|
||||
|
||||
def alertedToBlockingAppsRunning(self):
|
||||
@@ -257,9 +264,11 @@ class AlertController(NSObject):
|
||||
@AppHelper.endSheetMethod
|
||||
def blockingAppsRunningAlertDidEnd_returnCode_contextInfo_(
|
||||
self, alert, returncode, contextinfo):
|
||||
'''Called when blocking apps alert ends'''
|
||||
self._currentAlert = None
|
||||
|
||||
def getFirmwareAlertInfo(self):
|
||||
'''Get detail about a firmware update'''
|
||||
info = []
|
||||
for update_item in MunkiItems.getUpdateList():
|
||||
if 'firmware_alert_text' in update_item:
|
||||
@@ -340,15 +349,3 @@ class AlertController(NSObject):
|
||||
return True
|
||||
return False
|
||||
|
||||
@AppHelper.endSheetMethod
|
||||
def confirmLaterAlertDidEnd_returnCode_contextInfo_(
|
||||
self, alert, returncode, contextinfo):
|
||||
self._currentAlert = None
|
||||
if returncode == NSAlertAlternateReturn:
|
||||
msulog.log("user", "exit_later_clicked")
|
||||
NSApp.terminate_(self)
|
||||
|
||||
|
||||
def confirm(self):
|
||||
pass
|
||||
|
||||
|
||||
@@ -33,8 +33,6 @@ class MSUAppDelegate(NSObject):
|
||||
|
||||
mainWindowController = IBOutlet()
|
||||
statusController = IBOutlet()
|
||||
|
||||
managedsoftwareupdate_task = None
|
||||
|
||||
def applicationShouldTerminate_(self, sender):
|
||||
# called if user selects 'Quit' from menu
|
||||
@@ -52,26 +50,6 @@ class MSUAppDelegate(NSObject):
|
||||
# setup client logging
|
||||
msulog.setup_logging()
|
||||
|
||||
# register for notification messages so we can be told if available
|
||||
# updates change while we are open
|
||||
notification_center = NSDistributedNotificationCenter.defaultCenter()
|
||||
notification_center.addObserver_selector_name_object_suspensionBehavior_(
|
||||
self,
|
||||
self.updateAvailableUpdates,
|
||||
'com.googlecode.munki.managedsoftwareupdate.updateschanged',
|
||||
None,
|
||||
NSNotificationSuspensionBehaviorDeliverImmediately)
|
||||
|
||||
# register for notification messages so we can be told to
|
||||
# display a logout warning
|
||||
notification_center = NSDistributedNotificationCenter.defaultCenter()
|
||||
notification_center.addObserver_selector_name_object_suspensionBehavior_(
|
||||
self,
|
||||
self.forcedLogoutWarning,
|
||||
'com.googlecode.munki.ManagedSoftwareUpdate.logoutwarn',
|
||||
None,
|
||||
NSNotificationSuspensionBehaviorDeliverImmediately)
|
||||
|
||||
# have the statuscontroller register for its own notifications
|
||||
self.statusController.registerForNotifications()
|
||||
|
||||
@@ -86,43 +64,13 @@ class MSUAppDelegate(NSObject):
|
||||
lastcheck = munki.pref('LastCheckDate')
|
||||
# if there is no lastcheck timestamp, check for updates.
|
||||
if not lastcheck:
|
||||
self.checkForUpdates()
|
||||
self.mainWindowController.checkForUpdates()
|
||||
|
||||
# otherwise, only check for updates if the last check is over the
|
||||
# configured manualcheck cache age max.
|
||||
max_cache_age = munki.pref('CheckResultsCacheSeconds')
|
||||
if lastcheck.timeIntervalSinceNow() * -1 > int(max_cache_age):
|
||||
self.checkForUpdates()
|
||||
self.mainWindowController.checkForUpdates()
|
||||
|
||||
# show the default initial view
|
||||
self.mainWindowController.loadInitialView()
|
||||
|
||||
def updateAvailableUpdates(self):
|
||||
NSLog(u"Managed Software Center got update notification")
|
||||
if not self.mainWindowController._update_in_progress:
|
||||
self.mainWindowController.resetAndReload()
|
||||
|
||||
def forcedLogoutWarning(self, notification_obj):
|
||||
NSLog(u"Managed Software Center got forced logout warning")
|
||||
# hand it off to the main window
|
||||
self.mainWindowController.forcedLogoutWarning(notification_obj)
|
||||
|
||||
def munkiStatusSessionEnded_(self, socketSessionResult):
|
||||
NSLog(u"MunkiStatus session ended: %s" % socketSessionResult)
|
||||
NSLog(u"MunkiStatus session type: %s" % self.managedsoftwareupdate_task)
|
||||
# tell the main window
|
||||
tasktype = self.managedsoftwareupdate_task
|
||||
self.managedsoftwareupdate_task = None
|
||||
self.mainWindowController.munkiTaskEnded_withResult_(
|
||||
tasktype, socketSessionResult)
|
||||
|
||||
def checkForUpdates(self, suppress_apple_update_check=False):
|
||||
# kick off an update check
|
||||
# attempt to start the update check
|
||||
result = munki.startUpdateCheck(suppress_apple_update_check)
|
||||
if result == 0:
|
||||
self.managedsoftwareupdate_task = "manualcheck"
|
||||
self.statusController.startMunkiStatusSession()
|
||||
else:
|
||||
self.mainWindowController.theWindow.makeKeyAndOrderFront_(self)
|
||||
self.munkiStatusSessionEnded_(2)
|
||||
|
||||
@@ -41,6 +41,7 @@ class MSUMainWindowController(NSWindowController):
|
||||
_alertedUserToOutstandingUpdates = False
|
||||
|
||||
_update_in_progress = False
|
||||
managedsoftwareupdate_task = None
|
||||
_update_queue = set()
|
||||
|
||||
# status vars
|
||||
@@ -52,6 +53,7 @@ class MSUMainWindowController(NSWindowController):
|
||||
|
||||
html_dir = None
|
||||
|
||||
# Cocoa UI binding properties
|
||||
tabControl = IBOutlet()
|
||||
webView = IBOutlet()
|
||||
navigationBtn = IBOutlet()
|
||||
@@ -62,6 +64,7 @@ class MSUMainWindowController(NSWindowController):
|
||||
fullScreenMenuItem = IBOutlet()
|
||||
|
||||
def appShouldTerminate(self):
|
||||
'''called by app delegate when it receives applicationShouldTerminate:'''
|
||||
if self.getUpdateCount() == 0:
|
||||
# no pending updates
|
||||
return YES
|
||||
@@ -72,13 +75,13 @@ class MSUMainWindowController(NSWindowController):
|
||||
return YES
|
||||
if self.currentPageIsUpdatesPage() and self._alertedUserToOutstandingUpdates:
|
||||
return YES
|
||||
|
||||
# we have pending updates and we have not yet warned the user
|
||||
# about them
|
||||
self.alertToPendingUpdates()
|
||||
return NO
|
||||
|
||||
def alertToPendingUpdates(self):
|
||||
'''Alert user to pending updates before quitting the application'''
|
||||
self._alertedUserToOutstandingUpdates = True
|
||||
if munki.thereAreUpdatesToBeForcedSoon():
|
||||
alertTitle = NSLocalizedString(u"Mandatory Updates Pending",
|
||||
@@ -114,6 +117,7 @@ class MSUMainWindowController(NSWindowController):
|
||||
@AppHelper.endSheetMethod
|
||||
def updateAlertDidEnd_returnCode_contextInfo_(
|
||||
self, alert, returncode, contextinfo):
|
||||
'''Called when alert invoked by alertToPendingUpdates ends'''
|
||||
self._currentAlert = None
|
||||
if returncode == NSAlertDefaultReturn:
|
||||
msulog.log("user", "quit")
|
||||
@@ -128,6 +132,8 @@ class MSUMainWindowController(NSWindowController):
|
||||
self.loadUpdatesPage_(self)
|
||||
|
||||
def window_willPositionSheet_usingRect_(self, window, sheet, rect):
|
||||
'''NSWindowDelegate method that allows us to modify the
|
||||
position sheets appear attached to a window'''
|
||||
# move the anchor point of our sheets to below our toolbar
|
||||
# (or really, to the top of the web view)
|
||||
webViewRect = self.webView.frame()
|
||||
@@ -135,6 +141,7 @@ class MSUMainWindowController(NSWindowController):
|
||||
webViewRect.size.width, 0)
|
||||
|
||||
def loadInitialView(self):
|
||||
'''Called by app delegate from applicationDidFinishLaunching:'''
|
||||
if MunkiItems.getEffectiveUpdateList():
|
||||
self.loadUpdatesPage_(self)
|
||||
if not munki.thereAreUpdatesToBeForcedSoon():
|
||||
@@ -143,12 +150,12 @@ class MSUMainWindowController(NSWindowController):
|
||||
self.loadAllSoftwarePage_(self)
|
||||
self.displayUpdateCount()
|
||||
|
||||
@AppHelper.endSheetMethod
|
||||
def munkiSessionErrorAlertDidEnd_returnCode_contextInfo_(
|
||||
self, alert, returncode, contextinfo):
|
||||
self.resetAndReload()
|
||||
|
||||
def munkiTaskEnded_withResult_(self, tasktype, sessionResult):
|
||||
def munkiStatusSessionEnded_(self, sessionResult):
|
||||
'''Called by StatusController when a Munki session ends'''
|
||||
NSLog(u"MunkiStatus session ended: %s" % sessionResult)
|
||||
NSLog(u"MunkiStatus session type: %s" % self.managedsoftwareupdate_task)
|
||||
tasktype = self.managedsoftwareupdate_task
|
||||
self.managedsoftwareupdate_task = None
|
||||
self._update_in_progress = False
|
||||
|
||||
# The managedsoftwareupdate run will have changed state preferences
|
||||
@@ -212,10 +219,19 @@ class MSUMainWindowController(NSWindowController):
|
||||
self._update_queue.clear()
|
||||
self.updateNow()
|
||||
|
||||
@AppHelper.endSheetMethod
|
||||
def munkiSessionErrorAlertDidEnd_returnCode_contextInfo_(
|
||||
self, alert, returncode, contextinfo):
|
||||
'''Called when alert raised by munkiStatusSessionEnded ends'''
|
||||
self.resetAndReload()
|
||||
|
||||
def resetAndReload(self):
|
||||
'''Clear cached values, reload from disk. Display any changes.
|
||||
Typically called soon after a Munki session completes'''
|
||||
NSLog('resetAndReload method called')
|
||||
# need to clear out cached data
|
||||
MunkiItems.reset()
|
||||
# pending updates may have changed
|
||||
self._alertedUserToOutstandingUpdates = False
|
||||
# what page are we currently viewing?
|
||||
filename = self._current_page_filename
|
||||
@@ -245,19 +261,21 @@ class MSUMainWindowController(NSWindowController):
|
||||
self.displayUpdateCount()
|
||||
|
||||
def windowShouldClose_(self, sender):
|
||||
'''NSWindowDelegate method called when user closes a window'''
|
||||
# closing the main window should be the same as quitting
|
||||
NSApp.terminate_(self)
|
||||
return NO
|
||||
|
||||
def configureFullScreenMenuItem(self):
|
||||
# check to see if NSWindow's toggleFullScreen: selector is implemented.
|
||||
# if so, unhide the menu items for going full screen
|
||||
'''check to see if NSWindow's toggleFullScreen: selector is implemented.
|
||||
if so, unhide the menu items for going full screen'''
|
||||
if self.window().respondsToSelector_('toggleFullScreen:'):
|
||||
self.windowMenuSeperatorItem.setHidden_(False)
|
||||
self.fullScreenMenuItem.setHidden_(False)
|
||||
self.fullScreenMenuItem.setEnabled_(True)
|
||||
|
||||
def awakeFromNib(self):
|
||||
'''Stuff we need to intialize when we start'''
|
||||
self.configureFullScreenMenuItem()
|
||||
self.webView.setDrawsBackground_(NO)
|
||||
self.webView.setUIDelegate_(self)
|
||||
@@ -268,14 +286,56 @@ class MSUMainWindowController(NSWindowController):
|
||||
self.alert_controller = AlertController.alloc().init()
|
||||
self.alert_controller.setWindow_(self.window())
|
||||
self.html_dir = msulib.html_dir()
|
||||
|
||||
self.registerForNotifications()
|
||||
|
||||
def registerForNotifications(self):
|
||||
'''register for notification messages'''
|
||||
# register for notification if available updates change
|
||||
notification_center = NSDistributedNotificationCenter.defaultCenter()
|
||||
notification_center.addObserver_selector_name_object_suspensionBehavior_(
|
||||
self,
|
||||
self.updateAvailableUpdates,
|
||||
'com.googlecode.munki.managedsoftwareupdate.updateschanged',
|
||||
None,
|
||||
NSNotificationSuspensionBehaviorDeliverImmediately)
|
||||
|
||||
# register for notification to display a logout warning from the logouthelper
|
||||
notification_center = NSDistributedNotificationCenter.defaultCenter()
|
||||
notification_center.addObserver_selector_name_object_suspensionBehavior_(
|
||||
self,
|
||||
self.forcedLogoutWarning,
|
||||
'com.googlecode.munki.ManagedSoftwareUpdate.logoutwarn',
|
||||
None,
|
||||
NSNotificationSuspensionBehaviorDeliverImmediately)
|
||||
|
||||
def updateAvailableUpdates(self):
|
||||
'''If a Munki session is not in progress (that we know of) and
|
||||
we get a updateschanged notification, resetAndReload'''
|
||||
NSLog(u"Managed Software Center got update notification")
|
||||
if not self._update_in_progress:
|
||||
self.resetAndReload()
|
||||
|
||||
def forcedLogoutWarning(self, notification_obj):
|
||||
'''Received a logout warning from the logouthelper for an
|
||||
upcoming forced install'''
|
||||
NSLog(u"Managed Software Center got forced logout warning")
|
||||
# got a notification of an upcoming forced install
|
||||
# switch to updates view, then display alert
|
||||
self.loadUpdatesPage_(self)
|
||||
self.alert_controller.forcedLogoutWarning(notification_obj)
|
||||
|
||||
|
||||
def checkForUpdates(self, suppress_apple_update_check=False):
|
||||
'''start an update check session'''
|
||||
# attempt to start the update check
|
||||
result = munki.startUpdateCheck(suppress_apple_update_check)
|
||||
if result == 0:
|
||||
self.managedsoftwareupdate_task = "manualcheck"
|
||||
NSApp.delegate().statusController.startMunkiStatusSession()
|
||||
else:
|
||||
self.munkiStatusSessionEnded_(2)
|
||||
|
||||
def kickOffUpdateSession(self):
|
||||
'''start an update install/removal session'''
|
||||
# check for need to logout, restart, firmware warnings
|
||||
# warn about blocking applications, etc...
|
||||
# then start an update session
|
||||
@@ -291,7 +351,7 @@ class MSUMainWindowController(NSWindowController):
|
||||
if self.alert_controller.alertedToRunningOnBatteryAndCancelled():
|
||||
# do nothing
|
||||
return
|
||||
NSApp.delegate().managedsoftwareupdate_task = None
|
||||
self.managedsoftwareupdate_task = None
|
||||
msulog.log("user", "install_without_logout")
|
||||
self._update_in_progress = True
|
||||
self.displayUpdateCount()
|
||||
@@ -300,13 +360,15 @@ class MSUMainWindowController(NSWindowController):
|
||||
result = munki.justUpdate()
|
||||
if result:
|
||||
NSLog("Error starting install session: %s" % result)
|
||||
NSApp.delegate().munkiStatusSessionEnded_(2)
|
||||
self.munkiStatusSessionEnded_(2)
|
||||
else:
|
||||
NSApp.delegate().managedsoftwareupdate_task = "installwithnologout"
|
||||
self.managedsoftwareupdate_task = "installwithnologout"
|
||||
NSApp.delegate().statusController.startMunkiStatusSession()
|
||||
self.markPendingItemsAsInstalling()
|
||||
|
||||
def markPendingItemsAsInstalling(self):
|
||||
'''While an install/removal session is happening, mark optional items
|
||||
that are being installed/removed with the appropriate status'''
|
||||
install_info = munki.getInstallInfo()
|
||||
items_to_be_installed_names = [item['name']
|
||||
for item in install_info.get('managed_installs', [])]
|
||||
@@ -326,6 +388,9 @@ class MSUMainWindowController(NSWindowController):
|
||||
self.updateDOMforOptionalItem(item)
|
||||
|
||||
def updateNow(self):
|
||||
'''If user has added to/removed from the list of things to be updated,
|
||||
run a check session. If there are no more changes, proceed to an update
|
||||
installation session'''
|
||||
if self.stop_requested:
|
||||
# reset the flag
|
||||
self.stop_requested = False
|
||||
@@ -359,11 +424,14 @@ class MSUMainWindowController(NSWindowController):
|
||||
self.kickOffUpdateSession()
|
||||
|
||||
def getUpdateCount(self):
|
||||
'''Get the count of effective updates'''
|
||||
if self._update_in_progress:
|
||||
return 0
|
||||
return len(MunkiItems.getEffectiveUpdateList())
|
||||
|
||||
def displayUpdateCount(self):
|
||||
'''Display the update count as a badge in the window toolbar
|
||||
and as an icon badge in the Dock'''
|
||||
updateCount = self.getUpdateCount()
|
||||
btn_image = MSUBadgedTemplateImage.imageNamed_withCount_(
|
||||
'toolbarUpdatesTemplate.png', updateCount)
|
||||
@@ -374,21 +442,24 @@ class MSUMainWindowController(NSWindowController):
|
||||
NSApp.dockTile().setBadgeLabel_(None)
|
||||
|
||||
def updateMyItemsPage(self):
|
||||
'''Modifies the DOM to avoid ugly browser refresh'''
|
||||
'''Update the "My Items" page with current data.
|
||||
Modifies the DOM to avoid ugly browser refresh'''
|
||||
myitems_rows = msuhtml.build_myitems_rows()
|
||||
document = self.webView.mainFrameDocument()
|
||||
table_body_element = document.getElementById_('my_items_rows')
|
||||
table_body_element.setInnerHTML_(myitems_rows)
|
||||
|
||||
def updateCategoriesPage(self):
|
||||
'''Modifies DOM on currently displayed page to avoid nasty page refresh'''
|
||||
'''Update the Catagories page with current data.
|
||||
Modifies the DOM to avoid ugly browser refresh'''
|
||||
items_html = msulib.build_category_items_html()
|
||||
document = self.webView.mainFrameDocument()
|
||||
items_div_element = document.getElementById_('optional_installs_items')
|
||||
items_div_element.setInnerHTML_(items_html)
|
||||
|
||||
def updateListPage(self):
|
||||
'''Modifies DOM on currently displayed page to avoid nasty page refresh'''
|
||||
'''Update the optional items list page with current data.
|
||||
Modifies the DOM to avoid ugly browser refresh'''
|
||||
filename = self._current_page_filename
|
||||
if not filename:
|
||||
NSLog('updateListPage unexpected error: no _current_page_filename')
|
||||
@@ -419,16 +490,17 @@ class MSUMainWindowController(NSWindowController):
|
||||
items_div_element.setInnerHTML_(items_html)
|
||||
|
||||
def load_page(self, url_fragment):
|
||||
'''Tells the WebView to load the appropriate page'''
|
||||
html_file = os.path.join(self.html_dir, url_fragment)
|
||||
request = NSURLRequest.requestWithURL_cachePolicy_timeoutInterval_(
|
||||
NSURL.fileURLWithPath_(html_file), NSURLRequestReloadIgnoringLocalCacheData, 10)
|
||||
self.webView.mainFrame().loadRequest_(request)
|
||||
|
||||
def setNoPageCache(self):
|
||||
# We disable the back/forward page cache because
|
||||
# we generate each page dynamically; we want things
|
||||
# that are changed in one page view to be reflected
|
||||
# immediately in all page views
|
||||
'''We disable the back/forward page cache because
|
||||
we generate each page dynamically; we want things
|
||||
that are changed in one page view to be reflected
|
||||
immediately in all page views'''
|
||||
identifier = 'com.googlecode.munki.ManagedSoftwareCenter'
|
||||
prefs = WebPreferences.alloc().initWithIdentifier_(identifier)
|
||||
prefs.setUsesPageCache_(False)
|
||||
@@ -438,15 +510,16 @@ class MSUMainWindowController(NSWindowController):
|
||||
|
||||
def webView_decidePolicyForNewWindowAction_request_newFrameName_decisionListener_(
|
||||
self, webView, actionInformation, request, frameName, listener):
|
||||
# open link in default browser
|
||||
'''open link in default browser instead of in our app's WebView'''
|
||||
listener.ignore()
|
||||
NSWorkspace.sharedWorkspace().openURL_(request.URL())
|
||||
|
||||
def webView_resource_willSendRequest_redirectResponse_fromDataSource_(
|
||||
self, sender, identifier, request, redirectResponse, dataSource):
|
||||
'''By reacting to this delegate notification, we can build the page
|
||||
the WebView wants to load'''
|
||||
url = request.URL()
|
||||
if url.scheme() == 'file' and os.path.join(self.html_dir) in url.path():
|
||||
#NSLog(u'Got request for local file: %@', url.path())
|
||||
filename = url.lastPathComponent()
|
||||
if (filename.endswith('.html')
|
||||
and (filename.startswith('detail-')
|
||||
@@ -477,27 +550,35 @@ class MSUMainWindowController(NSWindowController):
|
||||
return request
|
||||
|
||||
def webView_didClearWindowObject_forFrame_(self, sender, windowScriptObject, frame):
|
||||
# Configure webView to let JavaScript talk to this object.
|
||||
'''Configure webView to let JavaScript talk to this object.'''
|
||||
self.windowScriptObject = windowScriptObject
|
||||
windowScriptObject.setValue_forKey_(self, 'AppController')
|
||||
|
||||
def webView_didStartProvisionalLoadForFrame_(self, view, frame):
|
||||
'''Animate progress spinner while we load a page'''
|
||||
self.progressSpinner.startAnimation_(self)
|
||||
|
||||
def webView_didFinishLoadForFrame_(self, view, frame):
|
||||
'''Stop progress spinner and update state of back/forward buttons'''
|
||||
self.progressSpinner.stopAnimation_(self)
|
||||
self.navigationBtn.setEnabled_forSegment_(self.webView.canGoBack(), 0)
|
||||
self.navigationBtn.setEnabled_forSegment_(self.webView.canGoForward(), 1)
|
||||
|
||||
def webView_didFailProvisionalLoadWithError_forFrame_(self, view, error, frame):
|
||||
'''Stop progress spinner and log'''
|
||||
self.progressSpinner.stopAnimation_(self)
|
||||
NSLog(u'Provisional load error: %@', error)
|
||||
files = os.listdir(self.html_dir)
|
||||
NSLog('Files in html_dir: %s' % files)
|
||||
|
||||
def webView_didFailLoadWithError_forFrame_(self, view, error, frame):
|
||||
'''Stop progress spinner and log error'''
|
||||
#TO-DO: display an error page?
|
||||
self.progressSpinner.stopAnimation_(self)
|
||||
NSLog('Committed load error: %@', error)
|
||||
|
||||
def isSelectorExcludedFromWebScript_(self, aSelector):
|
||||
'''Declare which methods can be called from JavaScript'''
|
||||
# For security, you must explicitly allow a selector to be called from JavaScript.
|
||||
if aSelector in ['actionButtonClicked:',
|
||||
'myItemsActionButtonClicked:',
|
||||
@@ -510,8 +591,8 @@ class MSUMainWindowController(NSWindowController):
|
||||
#### handling DOM UI elements ####
|
||||
|
||||
def installButtonClicked(self):
|
||||
# this method is called from JavaScript when the user
|
||||
# clicks the Install All button in the Updates view
|
||||
'''this method is called from JavaScript when the user
|
||||
clicks the Install button in the Updates view'''
|
||||
if self._update_in_progress:
|
||||
# this is now a stop/cancel button
|
||||
NSApp.delegate().statusController.disableStopButton()
|
||||
@@ -527,14 +608,14 @@ class MSUMainWindowController(NSWindowController):
|
||||
self._update_in_progress = True
|
||||
self.loadUpdatesPage_(self)
|
||||
self.displayUpdateCount()
|
||||
# yuck, this is in a different object than updateNow. We should normalize this.
|
||||
NSApp.delegate().checkForUpdates()
|
||||
self.checkForUpdates()
|
||||
else:
|
||||
# must say "Update"
|
||||
self.updateNow()
|
||||
self.loadUpdatesPage_(self)
|
||||
|
||||
def showUpdateProgressSpinner(self):
|
||||
'''This method is currently unused'''
|
||||
# update the status header on the updates page
|
||||
document = self.webView.mainFrameDocument()
|
||||
spinner = document.getElementById_('updates-progress-spinner')
|
||||
@@ -568,9 +649,9 @@ class MSUMainWindowController(NSWindowController):
|
||||
container_div.setClassName_(' '.join(container_div_classes))
|
||||
|
||||
def updateOptionalInstallButtonClicked_(self, item_name):
|
||||
# this method is called from JavaScript when a user clicks
|
||||
# the cancel or add button in the updates list
|
||||
# TO-DO: better handling of all the "unexpected error"s
|
||||
'''this method is called from JavaScript when a user clicks
|
||||
the cancel or add button in the updates list'''
|
||||
# TO-DO: better handling of all the possible "unexpected error"s
|
||||
document = self.webView.mainFrameDocument()
|
||||
item = MunkiItems.optionalItemForName_(item_name)
|
||||
if not item:
|
||||
@@ -641,8 +722,8 @@ class MSUMainWindowController(NSWindowController):
|
||||
self.displayUpdateCount()
|
||||
|
||||
def myItemsActionButtonClicked_(self, item_name):
|
||||
# this method is called from JavaScript when the user clicks
|
||||
# the Install/Removel/Cancel button in the My Items view
|
||||
'''this method is called from JavaScript when the user clicks
|
||||
the Install/Removel/Cancel button in the My Items view'''
|
||||
document = self.webView.mainFrameDocument()
|
||||
item = MunkiItems.optionalItemForName_(item_name)
|
||||
status_line = document.getElementById_('%s_status_text' % item_name)
|
||||
@@ -668,6 +749,7 @@ class MSUMainWindowController(NSWindowController):
|
||||
self.updateNow()
|
||||
|
||||
def updateDOMforOptionalItem(self, item):
|
||||
'''Update displayed status of an item'''
|
||||
document = self.webView.mainFrameDocument()
|
||||
status_line = document.getElementById_('%s_status_text' % item['name'])
|
||||
btn = document.getElementById_('%s_action_button_text' % item['name'])
|
||||
@@ -689,8 +771,8 @@ class MSUMainWindowController(NSWindowController):
|
||||
status_line.setClassName_(item['status'])
|
||||
|
||||
def actionButtonClicked_(self, item_name):
|
||||
# this method is called from JavaScript when the user clicks
|
||||
# the Install/Removel/Cancel button in the list or detail view
|
||||
'''this method is called from JavaScript when the user clicks
|
||||
the Install/Removel/Cancel button in the list or detail view'''
|
||||
item = MunkiItems.optionalItemForName_(item_name)
|
||||
if not item:
|
||||
NSLog('Can\'t find item: %s' % item_name)
|
||||
@@ -709,21 +791,26 @@ class MSUMainWindowController(NSWindowController):
|
||||
self._update_queue.discard(item['name'])
|
||||
|
||||
def changeSelectedCategory_(self, category):
|
||||
# this method is called from JavaScript when the user
|
||||
# changes the category selected in the sidebar popup
|
||||
'''this method is called from JavaScript when the user
|
||||
changes the category selected in the sidebar popup'''
|
||||
if category == 'All Categories':
|
||||
category = 'all'
|
||||
self.load_page('category-%s.html' % quote_plus(category))
|
||||
|
||||
def setStatusViewTitle_(self, title_text):
|
||||
'''When displaying status during a managedsoftwareupdate run, this method
|
||||
is used to disply info where the update count message usually is'''
|
||||
document = self.webView.mainFrameDocument()
|
||||
# we re-purpose the update count message for this
|
||||
update_count_element = document.getElementById_('update-count-string')
|
||||
if update_count_element:
|
||||
update_count_element.setInnerText_(title_text)
|
||||
|
||||
#### some Cocoa UI bindings #####
|
||||
|
||||
@IBAction
|
||||
def navigationBtnClicked_(self, sender):
|
||||
'''Handle WebView forward/back buttons'''
|
||||
segment = sender.selectedSegment()
|
||||
if segment == 0:
|
||||
self.webView.goBack_(self)
|
||||
@@ -732,22 +819,27 @@ class MSUMainWindowController(NSWindowController):
|
||||
|
||||
@IBAction
|
||||
def loadAllSoftwarePage_(self, sender):
|
||||
'''Called by Navigate menu item'''
|
||||
self.load_page('category-all.html')
|
||||
|
||||
@IBAction
|
||||
def loadCategoriesPage_(self, sender):
|
||||
'''Called by Navigate menu item'''
|
||||
self.load_page('categories.html')
|
||||
|
||||
@IBAction
|
||||
def loadMyItemsPage_(self, sender):
|
||||
'''Called by Navigate menu item'''
|
||||
self.load_page('myitems.html')
|
||||
|
||||
@IBAction
|
||||
def loadUpdatesPage_(self, sender):
|
||||
'''Called by Navigate menu item'''
|
||||
self.load_page('updates.html')
|
||||
|
||||
@IBAction
|
||||
def tabControlClicked_(self, sender):
|
||||
'''Handle a click on our toolbar buttons'''
|
||||
selectedCell = sender.selectedCell()
|
||||
if selectedCell:
|
||||
tag = selectedCell.tag()
|
||||
@@ -762,6 +854,7 @@ class MSUMainWindowController(NSWindowController):
|
||||
|
||||
@IBAction
|
||||
def searchFilterChanged_(self, sender):
|
||||
'''User changed the search field'''
|
||||
filterString = self.searchField.stringValue().lower()
|
||||
if filterString:
|
||||
self.load_page('filter-%s.html' % quote_plus(filterString))
|
||||
|
||||
@@ -65,8 +65,8 @@ class MSUStatusController(NSObject):
|
||||
self.receiving_notifications = False
|
||||
|
||||
def startMunkiStatusSession(self):
|
||||
'''Initialize things for monitoring a managedsoftwareupdate session'''
|
||||
self.initStatusSession()
|
||||
#self.registerForNotifications()
|
||||
self.session_started = True
|
||||
# start our process monitor timer so we can be notified about
|
||||
# process failure
|
||||
@@ -107,18 +107,20 @@ class MSUStatusController(NSObject):
|
||||
self.sessionEnded_(NEVER_STARTED)
|
||||
|
||||
def sessionStarted(self):
|
||||
'''Accessor method'''
|
||||
return self.session_started
|
||||
|
||||
def sessionEnded_(self, result):
|
||||
# clean up
|
||||
'''clean up after a managesoftwareupdate session ends'''
|
||||
if self.timer:
|
||||
self.timer.invalidate()
|
||||
self.timer = None
|
||||
self.cleanUpStatusSession()
|
||||
# tell the app the update session is done
|
||||
NSApp.delegate().munkiStatusSessionEnded_(result)
|
||||
# tell the window controller the update session is done
|
||||
self.statusWindowController.munkiStatusSessionEnded_(result)
|
||||
|
||||
def updateStatus_(self, notification):
|
||||
'''Got update status notification from managedsoftwareupdate'''
|
||||
self.got_status_update = True
|
||||
info = notification.userInfo()
|
||||
if 'message' in info:
|
||||
@@ -157,12 +159,14 @@ class MSUStatusController(NSObject):
|
||||
##### required status methods #####
|
||||
|
||||
def initStatusSession(self):
|
||||
'''Initialize the main window for update status'''
|
||||
self.statusWindowController._update_in_progress = True
|
||||
if self.statusWindowController.currentPageIsUpdatesPage():
|
||||
self.statusWindowController.webView.reload_(self)
|
||||
self.statusWindowController.displayUpdateCount()
|
||||
|
||||
def cleanUpStatusSession(self):
|
||||
'''Clean up after status session ends'''
|
||||
self.session_started = False
|
||||
# reset all our status variables
|
||||
self.statusWindowController._update_in_progress = False
|
||||
@@ -174,6 +178,7 @@ class MSUStatusController(NSObject):
|
||||
self._status_percent = -1
|
||||
|
||||
def setPercentageDone_(self, percent):
|
||||
'''Display precentage done'''
|
||||
try:
|
||||
if float(percent) > 100.0:
|
||||
percent = 100
|
||||
@@ -193,27 +198,30 @@ class MSUStatusController(NSObject):
|
||||
progress.setClassName_('')
|
||||
progress.setAttribute__('style', 'width: %s%%' % percent)
|
||||
|
||||
@AppHelper.endSheetMethod
|
||||
def restartAlertDidEnd_returnCode_contextInfo_(
|
||||
self, alert, returncode, contextinfo):
|
||||
self._status_restartAlertDismissed = 1
|
||||
# TO-DO: initiate actual restart
|
||||
|
||||
def doRestartAlert(self):
|
||||
'''Display a restart alert -- some item just installed or removed requires a restart'''
|
||||
self._status_restartAlertDismissed = 0
|
||||
alert = NSAlert.alertWithMessageText_defaultButton_alternateButton_otherButton_informativeTextWithFormat_(
|
||||
NSLocalizedString(u"Restart Required", None),
|
||||
NSLocalizedString(u"Restart", None),
|
||||
NSLocalizedString(u"Restart Required", u'RestartRequiredAlertText'),
|
||||
NSLocalizedString(u"Restart", u'RestartButtonText'),
|
||||
nil,
|
||||
nil,
|
||||
NSLocalizedString(
|
||||
u"Software installed or removed requires a restart. You will "
|
||||
"have a chance to save open documents.", None))
|
||||
"have a chance to save open documents.", u'RestartRequiredAlertDetail'))
|
||||
alert.beginSheetModalForWindow_modalDelegate_didEndSelector_contextInfo_(
|
||||
self.statusWindowController.window(),
|
||||
self, self.restartAlertDidEnd_returnCode_contextInfo_, nil)
|
||||
|
||||
@AppHelper.endSheetMethod
|
||||
def restartAlertDidEnd_returnCode_contextInfo_(
|
||||
self, alert, returncode, contextinfo):
|
||||
'''Called when restartAlert ends'''
|
||||
self._status_restartAlertDismissed = 1
|
||||
# TO-DO: initiate actual restart
|
||||
|
||||
def setMessage_(self, messageText):
|
||||
'''Display main status message'''
|
||||
self._status_message = messageText
|
||||
document = self.statusWindowController.webView.mainFrameDocument()
|
||||
spinner = document.getElementById_('updates-progress-spinner')
|
||||
@@ -226,6 +234,7 @@ class MSUStatusController(NSObject):
|
||||
textElement.setInnerHTML_(' ')
|
||||
|
||||
def setDetail_(self, detailText):
|
||||
'''Display status detail'''
|
||||
self._status_detail = detailText
|
||||
document = self.statusWindowController.webView.mainFrameDocument()
|
||||
spinner = document.getElementById_('updates-progress-spinner')
|
||||
@@ -238,9 +247,11 @@ class MSUStatusController(NSObject):
|
||||
textElement.setInnerHTML_(' ')
|
||||
|
||||
def getStopBtnState(self):
|
||||
'''Get the state (pressed or not) of the stop button'''
|
||||
return self._status_stopBtnState
|
||||
|
||||
def hideStopButton(self):
|
||||
'''Hide the stop button'''
|
||||
if self._status_stopBtnState:
|
||||
return
|
||||
self._status_stopBtnHidden = True
|
||||
@@ -255,6 +266,7 @@ class MSUStatusController(NSObject):
|
||||
install_btn.setClassName_(' '.join(btn_classes))
|
||||
|
||||
def showStopButton(self):
|
||||
'''Show the stop button'''
|
||||
if self._status_stopBtnState:
|
||||
return
|
||||
self._status_stopBtnHidden = False
|
||||
@@ -269,6 +281,7 @@ class MSUStatusController(NSObject):
|
||||
install_btn.setClassName_(' '.join(btn_classes))
|
||||
|
||||
def enableStopButton(self):
|
||||
'''Enable the stop button'''
|
||||
if self._status_stopBtnState:
|
||||
return
|
||||
self._status_stopBtnDisabled = False
|
||||
@@ -283,6 +296,7 @@ class MSUStatusController(NSObject):
|
||||
install_btn.setClassName_(' '.join(btn_classes))
|
||||
|
||||
def disableStopButton(self):
|
||||
'''Disable the stop button'''
|
||||
if self._status_stopBtnState:
|
||||
return
|
||||
self._status_stopBtnDisabled = True
|
||||
@@ -297,4 +311,5 @@ class MSUStatusController(NSObject):
|
||||
install_btn.setClassName_(' '.join(btn_classes))
|
||||
|
||||
def getRestartAlertDismissed(self):
|
||||
'''Was the restart alert dimissed?'''
|
||||
return self._status_restartAlertDismissed
|
||||
|
||||
@@ -135,17 +135,13 @@ def updatesContainNonOptionalItems():
|
||||
return True
|
||||
install_info = getInstallInfo()
|
||||
install_items = install_info.get('managed_installs', [])
|
||||
#NSLog('install_items: %s' % install_items)
|
||||
removal_items = install_info.get('removals', [])
|
||||
#NSLog('removal_items: %s' % removal_items)
|
||||
filtered_installs = [item for item in install_items
|
||||
if item['name'] not in SelfService().installs()]
|
||||
#NSLog('filtered_installs: %s' % filtered_installs)
|
||||
if filtered_installs:
|
||||
return True
|
||||
filtered_uninstalls = [item for item in removal_items
|
||||
if item['name'] not in SelfService().uninstalls()]
|
||||
#NSLog('filtered_uninstalls: %s' % filtered_uninstalls)
|
||||
if filtered_uninstalls:
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -21,6 +21,7 @@ from Foundation import NSLocalizedString
|
||||
|
||||
|
||||
def build_page(filename):
|
||||
'''Dispatch request to build a page to the appropriate function'''
|
||||
name = os.path.splitext(filename)[0]
|
||||
key, p, quoted_value = name.partition('-')
|
||||
value = unquote_plus(quoted_value)
|
||||
@@ -51,6 +52,7 @@ def write_page(page_name, html):
|
||||
|
||||
|
||||
def build_detail_page(item_name):
|
||||
'''Build page showing detail for a single optional item'''
|
||||
items = MunkiItems.getOptionalInstallItems()
|
||||
page_name = 'detail-%s.html' % quote_plus(item_name)
|
||||
for item in items:
|
||||
@@ -108,6 +110,7 @@ def build_detail_page(item_name):
|
||||
|
||||
|
||||
def build_list_page(category=None, developer=None, filter=None):
|
||||
'''Build page listing available optional items'''
|
||||
items = MunkiItems.getOptionalInstallItems()
|
||||
|
||||
header = 'All items'
|
||||
@@ -158,6 +161,7 @@ def build_list_page(category=None, developer=None, filter=None):
|
||||
|
||||
|
||||
def build_list_page_items_html(category=None, developer=None, filter=None):
|
||||
'''Returns HTML for the items on the list page'''
|
||||
items = MunkiItems.getOptionalInstallItems()
|
||||
item_html = ''
|
||||
if filter:
|
||||
@@ -221,6 +225,7 @@ def build_list_page_items_html(category=None, developer=None, filter=None):
|
||||
|
||||
|
||||
def build_categories_page():
|
||||
'''Build page showing available categories and some items in each one'''
|
||||
all_items = MunkiItems.getOptionalInstallItems()
|
||||
header = 'Categories'
|
||||
page_name = 'categories.html'
|
||||
@@ -247,6 +252,7 @@ def build_categories_page():
|
||||
|
||||
|
||||
def build_category_items_html():
|
||||
'''Returns HTML for the items on the Categories page'''
|
||||
all_items = MunkiItems.getOptionalInstallItems()
|
||||
if all_items:
|
||||
category_list = []
|
||||
@@ -302,6 +308,7 @@ def build_category_items_html():
|
||||
|
||||
|
||||
def build_myitems_page():
|
||||
'''Builds "My Items" page, which shows all current optional choices'''
|
||||
page_name = 'myitems.html'
|
||||
page_template = msulib.get_template('myitems_template.html')
|
||||
|
||||
@@ -316,6 +323,7 @@ def build_myitems_page():
|
||||
|
||||
|
||||
def build_myitems_rows():
|
||||
'''Returns HTML for the items on the 'My Items' page'''
|
||||
item_list = MunkiItems.getMyItemsList()
|
||||
if item_list:
|
||||
item_template = msulib.get_template('myitems_row_template.html')
|
||||
@@ -470,6 +478,7 @@ def get_warning_text():
|
||||
|
||||
|
||||
def build_updatedetail_page(item_name):
|
||||
'''Build detail page for a non-optional update'''
|
||||
items = MunkiItems.getUpdateList()
|
||||
page_name = 'updatedetail-%s.html' % quote_plus(item_name)
|
||||
for item in items:
|
||||
|
||||
@@ -105,6 +105,7 @@ class MSUHTMLFilter(HTMLParser):
|
||||
|
||||
|
||||
def filtered_html(text):
|
||||
'''Returns filtered HTML for use in description paragraphs'''
|
||||
parser = MSUHTMLFilter()
|
||||
parser.feed(text)
|
||||
if parser.tag_count:
|
||||
@@ -167,6 +168,7 @@ def updateCountMessage(count):
|
||||
|
||||
|
||||
def getInstallAllButtonTextForCount(count):
|
||||
'''Return localized display text for action button in Updates view'''
|
||||
if count == 0:
|
||||
return NSLocalizedString(u'Check Again',
|
||||
u'CheckAgainButtonLabel').encode('utf-8')
|
||||
|
||||
@@ -304,6 +304,7 @@ def trimVersionString(version_string):
|
||||
|
||||
|
||||
def getconsoleuser():
|
||||
'''Get current GUI user'''
|
||||
from SystemConfiguration import SCDynamicStoreCopyConsoleUser
|
||||
cfuser = SCDynamicStoreCopyConsoleUser( None, None, None )
|
||||
return cfuser[0]
|
||||
|
||||
Reference in New Issue
Block a user