def _create_date(self, form_item, val, form_view): gregorian = NSCalendar.alloc().initWithCalendarIdentifier_(NSGregorianCalendar) control_label = NSTextField.createLabelWithText_font_(form_item.label, self._system_font) control = NSDatePicker.alloc().initWithFrame_(NSZeroRect) control.setCalendar_(gregorian) control.setDatePickerElements_(NSYearMonthDatePickerElementFlag) control.setDrawsBackground_(YES) control.setDateValue_(NSDate.date()) control.setMinDate_(NSDate.date()) control.setMaxDate_(NSDate.dateWithString_('2029-12-31 23:59:59 +0600')) control.sizeToFit() control.setAction_(self.datePickerAction_) self._form_y_offset -= NSHeight(control.frame()) control.setFrameOrigin_(NSPoint(self._center_point, self._form_y_offset)) control_label.placeRelativeToControl_(control) return (control, control_label)
def _pyobjc_notify(message, title=None, subtitle=None, appIcon=None, contentImage=None, open_URL=None, delay=0, sound=False): swizzle(objc.lookUpClass('NSBundle'), b'bundleIdentifier', swizzled_bundleIdentifier) notification = NSUserNotification.alloc().init() notification.setInformativeText_(message) if title: notification.setTitle_(title) if subtitle: notification.setSubtitle_(subtitle) if appIcon: url = NSURL.alloc().initWithString_(appIcon) image = NSImage.alloc().initWithContentsOfURL_(url) notification.set_identityImage_(image) if contentImage: url = NSURL.alloc().initWithString_(contentImage) image = NSImage.alloc().initWithContentsOfURL_(url) notification.setContentImage_(image) if sound: notification.setSoundName_( "NSUserNotificationDefaultSoundName") notification.setDeliveryDate_( NSDate.dateWithTimeInterval_sinceDate_(delay, NSDate.date())) NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_( notification)
def notify(title, subtitle, info_text, delay=0, sound=False, userInfo={}): """ Python method to show a desktop notification on Mountain Lion. Where: title: Title of notification subtitle: Subtitle of notification info_text: Informative text of notification delay: Delay (in seconds) before showing the notification sound: Play the default notification sound userInfo: a dictionary that can be used to handle clicks in your app's applicationDidFinishLaunching:aNotification method """ from Foundation import NSDate from objc import lookUpClass NSUserNotification = lookUpClass('NSUserNotification') NSUserNotificationCenter = lookUpClass('NSUserNotificationCenter') notification = NSUserNotification.alloc().init() notification.setTitle_(title) notification.setSubtitle_(subtitle) notification.setInformativeText_(info_text) notification.setUserInfo_(userInfo) if sound: notification.setSoundName_("NSUserNotificationDefaultSoundName") notification.setDeliveryDate_(NSDate.dateWithTimeInterval_sinceDate_(delay, NSDate.date())) NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)
def _pyobjc_notify(message, title=None, subtitle=None, appIcon=None, contentImage=None, open_URL=None, delay=0, sound=False): swizzle(objc.lookUpClass('NSBundle'), b'bundleIdentifier', swizzled_bundleIdentifier) notification = NSUserNotification.alloc().init() notification.setInformativeText_(message) if title: notification.setTitle_(title) if subtitle: notification.setSubtitle_(subtitle) if appIcon: url = NSURL.alloc().initWithString_(appIcon) image = NSImage.alloc().initWithContentsOfURL_(url) notification.set_identityImage_(image) if contentImage: url = NSURL.alloc().initWithString_(contentImage) image = NSImage.alloc().initWithContentsOfURL_(url) notification.setContentImage_(image) if sound: notification.setSoundName_( "NSUserNotificationDefaultSoundName") notification.setDeliveryDate_( NSDate.dateWithTimeInterval_sinceDate_( delay, NSDate.date())) NSUserNotificationCenter.defaultUserNotificationCenter( ).scheduleNotification_(notification)
def run(config): """ starts self-control with custom parameters, depending on the weekday and the config """ check_if_running(config["username"]) try: schedule = next(s for s in config["block-schedules"] if is_schedule_active(s)) except StopIteration: syslog.syslog(syslog.LOG_ALERT, "No schedule is active at the moment. Shutting down.") exit(0) duration = get_duration_minutes(schedule["end-hour"], schedule["end-minute"]) set_selfcontrol_setting("BlockDuration", duration, config["username"]) set_selfcontrol_setting("BlockAsWhitelist", 1 if schedule.get("block-as-whitelist", False) else 0, config["username"]) if schedule.get("host-blacklist", None) is not None: set_selfcontrol_setting("HostBlacklist", schedule["host-blacklist"], config["username"]) elif config.get("host-blacklist", None) is not None: set_selfcontrol_setting("HostBlacklist", config["host-blacklist"], config["username"]) # In legacy mode manually set the BlockStartedDate, this should not be required anymore in future versions # of SelfControl. if config.get("legacy-mode", True): set_selfcontrol_setting("BlockStartedDate", NSDate.date(), config["username"]) # Start SelfControl subprocess.call(["{path}/Contents/MacOS/org.eyebeam.SelfControl".format(path=config["selfcontrol-path"]), str(getpwnam(config["username"]).pw_uid), "--install"]) syslog.syslog(syslog.LOG_ALERT, "SelfControl started for {min} minute(s).".format(min=duration))
def send_OS_X_notify(title, content, img_path): '''发送Mac桌面通知''' def swizzle(cls, SEL, func): old_IMP = cls.instanceMethodForSelector_(SEL) def wrapper(self, *args, **kwargs): return func(self, old_IMP, *args, **kwargs) new_IMP = objc.selector(wrapper, selector=old_IMP.selector, signature=old_IMP.signature) objc.classAddMethod(cls, SEL, new_IMP) def swizzled_bundleIdentifier(self, original): # Use iTunes icon for notification return 'com.apple.itunes' swizzle(objc.lookUpClass('NSBundle'), b'bundleIdentifier', swizzled_bundleIdentifier) notification = NSUserNotification.alloc().init() notification.setInformativeText_('') notification.setTitle_(title.decode('utf-8')) notification.setSubtitle_(content.decode('utf-8')) notification.setInformativeText_('') notification.setUserInfo_({}) if img_path is not None: image = NSImage.alloc().initWithContentsOfFile_(img_path) # notification.setContentImage_(image) notification.set_identityImage_(image) notification.setDeliveryDate_( NSDate.dateWithTimeInterval_sinceDate_(0, NSDate.date())) NSUserNotificationCenter.defaultUserNotificationCenter().\ scheduleNotification_(notification)
def send_OS_X_notify(title, content, img_path): '''发送Mac桌面通知''' def swizzle(cls, SEL, func): old_IMP = cls.instanceMethodForSelector_(SEL) def wrapper(self, *args, **kwargs): return func(self, old_IMP, *args, **kwargs) new_IMP = objc.selector(wrapper, selector=old_IMP.selector, signature=old_IMP.signature) objc.classAddMethod(cls, SEL, new_IMP) def swizzled_bundleIdentifier(self, original): # Use iTunes icon for notification return 'com.apple.itunes' swizzle(objc.lookUpClass('NSBundle'), b'bundleIdentifier', swizzled_bundleIdentifier) notification = NSUserNotification.alloc().init() notification.setInformativeText_('') notification.setTitle_(title.decode('utf-8')) notification.setSubtitle_(content.decode('utf-8')) notification.setInformativeText_('') notification.setUserInfo_({}) if img_path is not None: image = NSImage.alloc().initWithContentsOfFile_(img_path) # notification.setContentImage_(image) notification.set_identityImage_(image) notification.setDeliveryDate_( NSDate.dateWithTimeInterval_sinceDate_(0, NSDate.date()) ) NSUserNotificationCenter.defaultUserNotificationCenter().\ scheduleNotification_(notification)
def notification(title, subtitle, message, data=None, sound=True): """Send a notification to Notification Center (OS X 10.8+). If running on a version of macOS that does not support notifications, a ``RuntimeError`` will be raised. Apple says, "The userInfo content must be of reasonable serialized size (less than 1k) or an exception will be thrown." So don't do that! :param title: text in a larger font. :param subtitle: text in a smaller font below the `title`. :param message: text representing the body of the notification below the `subtitle`. :param data: will be passed to the application's "notification center" (see :func:`rumps.notifications`) when this notification is clicked. :param sound: whether the notification should make a noise when it arrives. """ if not _NOTIFICATIONS: raise RuntimeError('OS X 10.8+ is required to send notifications') if data is not None and not isinstance(data, Mapping): raise TypeError('notification data must be a mapping') _require_string_or_none(title, subtitle, message) notification = NSUserNotification.alloc().init() notification.setTitle_(title) notification.setSubtitle_(subtitle) notification.setInformativeText_(message) notification.setUserInfo_({} if data is None else data) if sound: notification.setSoundName_("NSUserNotificationDefaultSoundName") notification.setDeliveryDate_( NSDate.dateWithTimeInterval_sinceDate_(0, NSDate.date())) notification_center = _default_user_notification_center() notification_center.scheduleNotification_(notification)
def notification(title, subtitle, message, data=None, sound=True, image=None): """Send a notification to Notification Center (Mac OS X 10.8+). If running on a version of Mac OS X that does not support notifications, a ``RuntimeError`` will be raised. Apple says, "The userInfo content must be of reasonable serialized size (less than 1k) or an exception will be thrown." So don't do that! :param title: text in a larger font. :param subtitle: text in a smaller font below the `title`. :param message: text representing the body of the notification below the `subtitle`. :param data: will be passed to the application's "notification center" (see :func:`rumps.notifications`) when this notification is clicked. :param sound: whether the notification should make a noise when it arrives. """ if not _NOTIFICATIONS: raise RuntimeError('Mac OS X 10.8+ is required to send notifications') if data is not None and not isinstance(data, Mapping): raise TypeError('notification data must be a mapping') _require_string_or_none(title, subtitle, message) notification = NSUserNotification.alloc().init() notification.setTitle_(title) notification.setSubtitle_(subtitle) notification.setInformativeText_(message) notification.setUserInfo_({} if data is None else data) if sound: notification.setSoundName_("NSUserNotificationDefaultSoundName") if image != None: notification.setContentImage_(image) notification.setDeliveryDate_(NSDate.dateWithTimeInterval_sinceDate_(0, NSDate.date())) NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)
def run(config): """ starts self-control with custom parameters, depending on the weekday and the config """ if check_if_running(config["username"]): syslog.syslog(syslog.LOG_ALERT, "SelfControl is already running, ignore current execution of Auto-SelfControl.") exit(2) try: schedule = next(s for s in config["block-schedules"] if is_schedule_active(s)) except StopIteration: syslog.syslog(syslog.LOG_ALERT, "No schedule is active at the moment. Shutting down.") exit(0) duration = get_duration_minutes(schedule["end-hour"], schedule["end-minute"]) set_selfcontrol_setting("BlockDuration", duration, config["username"]) set_selfcontrol_setting("BlockAsWhitelist", 1 if schedule.get("block-as-whitelist", False) else 0, config["username"]) if schedule.get("host-blacklist", None) is not None: set_selfcontrol_setting("HostBlacklist", schedule["host-blacklist"], config["username"]) elif config.get("host-blacklist", None) is not None: set_selfcontrol_setting("HostBlacklist", config["host-blacklist"], config["username"]) # In legacy mode manually set the BlockStartedDate, this should not be required anymore in future versions # of SelfControl. if config.get("legacy-mode", True): set_selfcontrol_setting("BlockStartedDate", NSDate.date(), config["username"]) # Start SelfControl subprocess.check_output(["{path}/Contents/MacOS/org.eyebeam.SelfControl".format(path=config["selfcontrol-path"]), str(getpwnam(config["username"]).pw_uid), "--install"]) syslog.syslog(syslog.LOG_ALERT, "SelfControl started for {min} minute(s).".format(min=duration))
def start(self): if not self._status: self._nsdate = NSDate.date() self._nstimer = NSTimer.alloc().initWithFireDate_interval_target_selector_userInfo_repeats_( self._nsdate, self._interval, self, 'callback:', None, True) NSRunLoop.currentRunLoop().addTimer_forMode_(self._nstimer, NSDefaultRunLoopMode) _TIMERS.add(self) self._status = True
def __init__(self, callback, interval): self.set_callback(callback) self._nsdate = NSDate.date() self._nstimer = NSTimer.alloc( ).initWithFireDate_interval_target_selector_userInfo_repeats_( self._nsdate, interval, self, 'callback:', None, True) NSRunLoop.currentRunLoop().addTimer_forMode_(self._nstimer, NSDefaultRunLoopMode)
def GET(url): """Return the contents of a url (from cache if possible)""" opener = urllib2.build_opener(CacheHandler("/tmp/plod")) response = opener.open(url) last_mod = _date_parser.dateFromString_(response.headers.get('Last-Modified')) if not last_mod: last_mod = NSDate.date() return response, last_mod.timeIntervalSince1970()
def GET(url): """Return the contents of a url (from cache if possible)""" opener = urllib2.build_opener(CacheHandler("/tmp/plod")) response = opener.open(url) last_mod = _date_parser.dateFromString_( response.headers.get('Last-Modified')) if not last_mod: last_mod = NSDate.date() return response, last_mod.timeIntervalSince1970()
def check_for_software_updates(self, force_check=True): """Check if Apple Software Updates are available, if needed or forced. Args: force_check: Boolean. If True, forces a check, otherwise only checks if the last check is deemed outdated. Returns: Boolean. True if there are updates, False otherwise. """ before_hash = munkihash.getsha256hash( self.applesync.apple_download_catalog_path) msg = 'Checking Apple Software Update catalog...' self._display_status_major(msg) try: self.applesync.cache_apple_catalog() except sync.CatalogNotFoundError: return False except (sync.ReplicationError, fetch.Error) as err: display.display_warning('Could not download Apple SUS catalog:') display.display_warning('\t%s', unicode(err)) return False if not force_check and not self._force_check_necessary(before_hash): display.display_info( 'Skipping Apple Software Update check ' 'because sucatalog is unchanged, installed Apple packages are ' 'unchanged and we recently did a full check.') # return True if we have cached updates; False otherwise return bool(self.software_update_info()) if self.download_available_updates(): # Success; ready to install. prefs.set_pref('LastAppleSoftwareUpdateCheck', NSDate.date()) product_ids = self.available_update_product_ids() if not product_ids: # No updates found self.applesync.clean_up_cache() return False os_version_tuple = osutils.getOsVersion(as_tuple=True) if os_version_tuple < (10, 11): self.applesync.write_filtered_catalog(product_ids) try: self.applesync.cache_update_metadata(product_ids) except sync.ReplicationError as err: display.display_warning( 'Could not replicate software update metadata:') display.display_warning('\t%s', unicode(err)) return False return True else: # Download error, allow check again soon. display.display_error( 'Could not download all available Apple updates.') prefs.set_pref('LastAppleSoftwareUpdateCheck', None) return False
def check_for_software_updates(self, force_check=True): """Check if Apple Software Updates are available, if needed or forced. Args: force_check: Boolean. If True, forces a check, otherwise only checks if the last check is deemed outdated. Returns: Integer. -1 if there was an error, otherwise the number of available updates. """ before_hash = munkihash.getsha256hash( self.applesync.apple_download_catalog_path) msg = 'Checking Apple Software Update catalog...' display.display_status_major(msg) try: self.applesync.cache_apple_catalog() except sync.CatalogNotFoundError: return -1 except (sync.ReplicationError, fetch.Error) as err: display.display_warning( 'Could not download Apple SUS catalog:') display.display_warning(u'\t%s', err) return -1 if not force_check and not self._force_check_necessary(before_hash): display.display_info( 'Skipping Apple Software Update check ' 'because sucatalog is unchanged, installed Apple packages are ' 'unchanged and we recently did a full check.') # return count of cached updates return len(self.software_update_info()) if self.download_available_updates(): # Success; ready to install. prefs.set_pref('LastAppleSoftwareUpdateCheck', NSDate.date()) product_ids = self.available_update_product_ids() if not product_ids: # No updates found self.applesync.clean_up_cache() return 0 try: self.applesync.cache_update_metadata(product_ids) except sync.ReplicationError as err: display.display_warning( 'Could not replicate software update metadata:') display.display_warning(u'\t%s', err) return -1 return len(product_ids) else: # Download error, allow check again soon. display.display_error( 'Could not download all available Apple updates.') prefs.set_pref('LastAppleSoftwareUpdateCheck', None) return 0
def check_for_software_updates(self, force_check=True): """Check if Apple Software Updates are available, if needed or forced. Args: force_check: Boolean. If True, forces a check, otherwise only checks if the last check is deemed outdated. Returns: Boolean. True if there are updates, False otherwise. """ before_hash = munkihash.getsha256hash( self.applesync.apple_download_catalog_path) msg = 'Checking Apple Software Update catalog...' display.display_status_major(msg) try: self.applesync.cache_apple_catalog() except sync.CatalogNotFoundError: return False except (sync.ReplicationError, fetch.Error) as err: display.display_warning( 'Could not download Apple SUS catalog:') display.display_warning('\t%s', unicode(err)) return False if not force_check and not self._force_check_necessary(before_hash): display.display_info( 'Skipping Apple Software Update check ' 'because sucatalog is unchanged, installed Apple packages are ' 'unchanged and we recently did a full check.') # return True if we have cached updates; False otherwise return bool(self.software_update_info()) if self.download_available_updates(): # Success; ready to install. prefs.set_pref('LastAppleSoftwareUpdateCheck', NSDate.date()) product_ids = self.available_update_product_ids() if not product_ids: # No updates found self.applesync.clean_up_cache() return False try: self.applesync.cache_update_metadata(product_ids) except sync.ReplicationError as err: display.display_warning( 'Could not replicate software update metadata:') display.display_warning('\t%s', unicode(err)) return False return True else: # Download error, allow check again soon. display.display_error( 'Could not download all available Apple updates.') prefs.set_pref('LastAppleSoftwareUpdateCheck', None) return False
def notify(title, subtitle, msg_text, sound=False): # Function to generate OS X notification. NSUserNotification = lookUpClass("NSUserNotification") NSUserNotificationCenter = lookUpClass("NSUserNotificationCenter") notification = NSUserNotification.alloc().init() notification.setTitle_(title) notification.setSubtitle_(subtitle) notification.setInformativeText_(msg_text) if sound: notification.setSoundName_("NSUserNotificationDefaultSoundName") notification.setDeliveryDate_(NSDate.dateWithTimeInterval_sinceDate_(0, NSDate.date())) NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)
def save_pending_update_times(): '''Record the time each update first is made available. We can use this to escalate our notifications if there are items that have been skipped a lot ''' now = NSDate.date() managed_install_dir = prefs.pref('ManagedInstallDir') pendingupdatespath = os.path.join(managed_install_dir, 'UpdateNotificationTracking.plist') installinfo = get_installinfo() install_names = [ item['name'] for item in installinfo.get('managed_installs', []) ] removal_names = [item['name'] for item in installinfo.get('removals', [])] apple_updates = get_appleupdates_with_history() update_names = { 'managed_installs': install_names, 'removals': removal_names, 'AppleUpdates': apple_updates.keys() } try: prior_pending_updates = FoundationPlist.readPlist(pendingupdatespath) except FoundationPlist.NSPropertyListSerializationException: prior_pending_updates = {} current_pending_updates = {} for category in update_names: current_pending_updates[category] = {} for name in update_names[category]: if (category in prior_pending_updates and name in prior_pending_updates[category]): # copy the prior datetime from matching item current_pending_updates[category][ name] = prior_pending_updates[category][name] else: if category == 'AppleUpdates': current_pending_updates[category][name] = apple_updates[ name] else: # record new item with current datetime current_pending_updates[category][name] = now try: FoundationPlist.writePlist(current_pending_updates, pendingupdatespath) except FoundationPlist.NSPropertyListWriteException: # we tried! oh well pass
def thereAreUpdatesToBeForcedSoon(hours=72): '''Return True if any updates need to be installed within the next X hours, false otherwise''' installinfo = getInstallInfo() if installinfo: now = NSDate.date() now_xhours = NSDate.dateWithTimeIntervalSinceNow_(hours * 3600) for item in installinfo.get('managed_installs', []): force_install_after_date = item.get('force_install_after_date') if force_install_after_date: force_install_after_date = discardTimeZoneFromDate( force_install_after_date) if now_xhours >= force_install_after_date: return True return False
def notification(title, subtitle, message, data=None, sound=True): """ Notification sender. Apple says, "The userInfo content must be of reasonable serialized size (less than 1k) or an exception will be thrown." So don't do that! """ if data is not None and not isinstance(data, Mapping): raise TypeError('notification data must be a mapping') notification = NSUserNotification.alloc().init() notification.setTitle_(title) notification.setSubtitle_(subtitle) notification.setInformativeText_(message) notification.setUserInfo_({} if data is None else data) if sound: notification.setSoundName_("NSUserNotificationDefaultSoundName") notification.setDeliveryDate_(NSDate.dateWithTimeInterval_sinceDate_(0, NSDate.date())) NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)
def oldest_pending_update_in_days(): '''Return the datestamp of the oldest pending update''' pendingupdatespath = os.path.join( prefs.pref('ManagedInstallDir'), 'UpdateNotificationTracking.plist') try: pending_updates = FoundationPlist.readPlist(pendingupdatespath) except FoundationPlist.NSPropertyListSerializationException: return 0 oldest_date = now = NSDate.date() for category in pending_updates: for name in pending_updates[category]: this_date = pending_updates[category][name] if this_date < oldest_date: oldest_date = this_date return now.timeIntervalSinceDate_(oldest_date) / (24 * 60 * 60)
def send_OS_X_notify(title, content, img_path): '''发送Mac桌面通知''' try: from Foundation import ( NSDate, NSUserNotification, NSUserNotificationCenter) from AppKit import NSImage import objc except ImportError: logger.info('failed to init OSX notify!') return def swizzle(cls, SEL, func): old_IMP = getattr(cls, SEL, None) if old_IMP is None: old_IMP = cls.instanceMethodForSelector_(SEL) def wrapper(self, *args, **kwargs): return func(self, old_IMP, *args, **kwargs) new_IMP = objc.selector(wrapper, selector=old_IMP.selector, signature=old_IMP.signature) objc.classAddMethod(cls, SEL.encode(), new_IMP) def swizzled_bundleIdentifier(self, original): # Use iTunes icon for notification return 'com.apple.itunes' swizzle(objc.lookUpClass('NSBundle'), 'bundleIdentifier', swizzled_bundleIdentifier) notification = NSUserNotification.alloc().init() notification.setTitle_(title) notification.setSubtitle_(content) notification.setInformativeText_('') notification.setUserInfo_({}) if img_path is not None: image = NSImage.alloc().initWithContentsOfFile_(img_path) # notification.setContentImage_(image) notification.set_identityImage_(image) notification.setDeliveryDate_( NSDate.dateWithTimeInterval_sinceDate_(0, NSDate.date()) ) NSUserNotificationCenter.defaultUserNotificationCenter().\ scheduleNotification_(notification) logger.info('send notify success!')
def oldest_pending_update_in_days(): '''Return the datestamp of the oldest pending update''' pendingupdatespath = os.path.join(prefs.pref('ManagedInstallDir'), 'UpdateNotificationTracking.plist') try: pending_updates = FoundationPlist.readPlist(pendingupdatespath) except FoundationPlist.NSPropertyListSerializationException: return 0 oldest_date = now = NSDate.date() for category in pending_updates: for name in pending_updates[category]: this_date = pending_updates[category][name] if this_date < oldest_date: oldest_date = this_date return now.timeIntervalSinceDate_(oldest_date) / (24 * 60 * 60)
def run_api_v2(config): """Start SelfControl (< 3.0) with custom parameters, depending on the weekday and the config""" if check_if_running(Api.V2, config): print "SelfControl is already running, exit" LOGGER.error( "SelfControl is already running, ignore current execution of Auto-SelfControl." ) exit(2) try: schedule = next(s for s in config["block-schedules"] if is_schedule_active(s)) except StopIteration: print("No Schedule is active at the moment.") LOGGER.warn("No schedule is active at the moment. Shutting down.") exit(0) duration = get_duration_minutes(schedule["end-hour"], schedule["end-minute"]) set_selfcontrol_setting("BlockDuration", duration, config["username"]) set_selfcontrol_setting( "BlockAsWhitelist", 1 if schedule.get("block-as-whitelist", False) else 0, config["username"]) if schedule.get("host-blacklist", None) is not None: set_selfcontrol_setting("HostBlacklist", schedule["host-blacklist"], config["username"]) elif config.get("host-blacklist", None) is not None: set_selfcontrol_setting("HostBlacklist", config["host-blacklist"], config["username"]) # In legacy mode manually set the BlockStartedDate, this should not be required anymore in future versions # of SelfControl. if config.get("legacy-mode", True): set_selfcontrol_setting("BlockStartedDate", NSDate.date(), config["username"]) # Start SelfControl execSelfControl(config, ["--install"]) LOGGER.info( "SelfControl started for {min} minute(s).".format(min=duration))
def save_pending_update_times(): '''Record the time each update first is made available. We can use this to escalate our notifications if there are items that have been skipped a lot ''' now = NSDate.date() managed_install_dir = prefs.pref('ManagedInstallDir') pendingupdatespath = os.path.join( managed_install_dir, 'UpdateNotificationTracking.plist') installinfo = get_installinfo() install_names = [item['name'] for item in installinfo.get('managed_installs', [])] removal_names = [item['name'] for item in installinfo.get('removals', [])] appleupdatesinfo = get_appleupdates() appleupdate_names = [item['name'] for item in appleupdatesinfo.get('AppleUpdates', [])] update_names = { 'managed_installs': install_names, 'removals': removal_names, 'AppleUpdates': appleupdate_names} try: prior_pending_updates = FoundationPlist.readPlist(pendingupdatespath) except FoundationPlist.NSPropertyListSerializationException: prior_pending_updates = {} current_pending_updates = {} for category in update_names: current_pending_updates[category] = {} for name in update_names[category]: if (category in prior_pending_updates and name in prior_pending_updates[category]): # copy the prior datetime from matching item current_pending_updates[category][name] = prior_pending_updates[ category][name] else: # record new item with current datetime current_pending_updates[category][name] = now try: FoundationPlist.writePlist(current_pending_updates, pendingupdatespath) except FoundationPlist.NSPropertyListWriteException: # we tried! oh well pass
def alert(self, title, subtitle, message, delay=0, sound=False, userInfo={}): self.notification.setTitle_(title) self.notification.setSubtitle_(subtitle) self.notification.setInformativeText_(message) self.notification.setDeliveryDate_( NSDate.dateWithTimeInterval_sinceDate_(delay, NSDate.date())) self.notification.setUserInfo_(userInfo) if sound: self.notification.setSoundName_( "NSUserNotificationDefaultSoundName") NSUserNotificationCenter.defaultUserNotificationCenter( ).scheduleNotification_(self.notification)
def get_appleupdates_with_history(): '''Attempt to find the date Apple Updates were first seen since they can appear and disappear from the list of available updates, which screws up our tracking of pending updates that can trigger more aggressive update notifications. Returns a dict.''' now = NSDate.date() managed_install_dir = prefs.pref('ManagedInstallDir') appleupdatehistorypath = os.path.join(managed_install_dir, 'AppleUpdateHistory.plist') appleupdatesinfo = get_appleupdates().get('AppleUpdates', []) history_info = {} if appleupdatesinfo: try: appleupdateshistory = FoundationPlist.readPlist( appleupdatehistorypath) except FoundationPlist.NSPropertyListSerializationException: appleupdateshistory = {} history_updated = False for item in appleupdatesinfo: product_key = item.get('productKey') if not product_key: continue if product_key in appleupdateshistory: history_info[item['name']] = ( appleupdateshistory[product_key].get('firstSeen', now)) else: history_info[item['name']] = now # record this for the future appleupdateshistory[product_key] = { 'firstSeen': now, 'displayName': item.get('display_name', ''), 'version': item.get('version_to_install', '') } history_updated = True if history_updated: try: FoundationPlist.writePlist(appleupdateshistory, appleupdatehistorypath) except FoundationPlist.NSPropertyListWriteException: # we tried! oh well pass return history_info
def thereAreUpdatesToBeForcedSoon(hours=72): '''Return True if any updates need to be installed within the next X hours, false otherwise''' installinfo = getInstallInfo().get('managed_installs', []) installinfo.extend(getAppleUpdates().get('AppleUpdates', [])) if installinfo: now = NSDate.date() now_xhours = NSDate.dateWithTimeIntervalSinceNow_(hours * 3600) for item in installinfo: force_install_after_date = item.get('force_install_after_date') if force_install_after_date: try: force_install_after_date = discardTimeZoneFromDate( force_install_after_date) if now_xhours >= force_install_after_date: return True except BadDateError: # some issue with the stored date pass return False
def save_pending_update_times(): '''Record the time each update first is made available. We can use this to escalate our notifications if there are items that have been skipped a lot ''' now = NSDate.date() managed_install_dir = prefs.pref('ManagedInstallDir') pendingupdatespath = os.path.join( managed_install_dir, 'UpdateNotificationTracking.plist') installinfo = get_installinfo() install_names = [item['name'] for item in installinfo.get('managed_installs', [])] removal_names = [item['name'] for item in installinfo.get('removals', [])] appleupdatesinfo = get_appleupdates() appleupdate_names = [item['name'] for item in appleupdatesinfo.get('AppleUpdates', [])] update_names = { 'managed_installs': install_names, 'removals': removal_names, 'AppleUpdates': appleupdate_names} try: pending_updates = FoundationPlist.readPlist(pendingupdatespath) except FoundationPlist.NSPropertyListSerializationException: pending_updates = {} for category in update_names: if category not in pending_updates: pending_updates[category] = {} for name in update_names[category]: if name not in pending_updates[category]: pending_updates[category][name] = now for name in pending_updates[category]: if name not in update_names[category]: del pending_updates[category][name] FoundationPlist.writePlist(pending_updates, pendingupdatespath)
def force_install_package_check(): """Check installable packages and applicable Apple updates for force install parameters. This method modifies InstallInfo and/or AppleUpdates in one scenario: It enables the unattended_install flag on all packages which need to be force installed and do not have a RestartAction. The return value may be one of: 'now': a force install is about to occur 'soon': a force install will occur within FORCE_INSTALL_WARNING_HOURS 'logout': a force install is about to occur and requires logout 'restart': a force install is about to occur and requires restart None: no force installs are about to occur """ result = None managed_install_dir = prefs.pref('ManagedInstallDir') installinfo_types = { 'InstallInfo.plist' : 'managed_installs', 'AppleUpdates.plist': 'AppleUpdates' } now = NSDate.date() now_xhours = NSDate.dateWithTimeIntervalSinceNow_( FORCE_INSTALL_WARNING_HOURS * 3600) for installinfo_plist in installinfo_types: pl_dict = installinfo_types[installinfo_plist] installinfopath = os.path.join(managed_install_dir, installinfo_plist) try: installinfo = FoundationPlist.readPlist(installinfopath) except FoundationPlist.NSPropertyListSerializationException: continue writeback = False for i in xrange(len(installinfo.get(pl_dict, []))): install = installinfo[pl_dict][i] force_install_after_date = install.get('force_install_after_date') if not force_install_after_date: continue force_install_after_date = ( info.subtract_tzoffset_from_date(force_install_after_date)) display.display_debug1( 'Forced install for %s at %s', install['name'], force_install_after_date) if now >= force_install_after_date: result = 'now' if install.get('RestartAction'): if install['RestartAction'] == 'RequireLogout': result = 'logout' elif (install['RestartAction'] == 'RequireRestart' or install['RestartAction'] == 'RecommendRestart'): result = 'restart' elif not install.get('unattended_install', False): display.display_debug1( 'Setting unattended install for %s', install['name']) install['unattended_install'] = True installinfo[pl_dict][i] = install writeback = True if not result and now_xhours >= force_install_after_date: result = 'soon' if writeback: FoundationPlist.writePlist(installinfo, installinfopath) return result
def __init__(self, callback, interval): self.set_callback(callback) self._nsdate = NSDate.date() self._nstimer = NSTimer.alloc().initWithFireDate_interval_target_selector_userInfo_repeats_( self._nsdate, interval, self, 'callback:', None, True) NSRunLoop.currentRunLoop().addTimer_forMode_(self._nstimer, NSDefaultRunLoopMode)
def main(): # State variables global sippySIPLaunchAgent global sippySIPAgentScript global sippysipLAId global writePlistPath currentUserUid = getConsoleUser() userId = str(getConsoleUser()[1]) pendingReboot = False # Check SIP Status SippySIPLog('Checking SIP State...') sipCsrutilDisabled = csrutil('status') SippySIPLog('Checking NVRAM SIP State...') sipNVRAMDisabled = nvram() # If SIP is disabled, we need to do $things. if sipCsrutilDisabled: SippySIPLog('Detected SIP Disabled via csrutil. Checking against ' 'NVRAM entries...') if sipNVRAMDisabled: SippySIPLog('Detected SIP Disabled via NVRAM.') SippySIPLog('Attempting to Re-Enable SIP...') sipCsrutilClear = csrutil('clear') if sipCsrutilClear: SippySIPLog('SIP Re-Enabled - Logging event to plist.') timestamp = NSDate.date() sippysipPlist = writePlist(timestamp, writePlistPath) pendingReboot = True else: SippySIPLog('Detected SIP Enabled via NVRAM. Device pending ' 'reboot...') pendingReboot = True # If csrutil says things are cool, let's just validate against NVRAM. else: SippySIPLog('Detected SIP Enabled via csrutil. Checking against ' 'NVRAM entries...') # Some kind of fuckery is going on here, so let's clear it and log. if sipNVRAMDisabled: SippySIPLog('Detected SIP Disabled via NVRAM.') SippySIPLog('Attempting to Re-Enable SIP...') sipCsrutilClear = csrutil('clear') if sipCsrutilClear: SippySIPLog('SIP Re-Enabled - Logging event to plist.') timestamp = NSDate.date() sippysipPlist = writePlist(timestamp, writePlistPath) pendingReboot = True else: SippySIPLog('SIP has been validated and is enabled.') exit(0) # If we are pending reboot, we should send a Yo notification to the user # informing them that it's time to reboot. if pendingReboot: SippySIPLog('Device is pending reboot - triggering user alert.') if (currentUserUid[0] is None or currentUserUid[0] == u'loginwindow' or currentUserUid[0] == u'_mbsetupuser'): SippySIPLog('No user logged in - Skipping Yo notification...') else: # sippysip's agent variables sippysipLAPlist = sippysipLAId + '.plist' sippysipPath = os.path.join('/Library', 'Application Support', 'sippysip') sippysipAgentPath = os.path.join(sippysipPath, 'sippysipagent.py') sippysipLAPath = os.path.join('/Library', 'LaunchAgents', sippysipLAPlist) sippysipWatchPath = '/Users/Shared/.sippysip' # Create sippysip's agent folder, script and agent. SippySIPLog('Creating sippysip agent folder and files...') if not os.path.isdir(sippysipPath): os.makedirs(sippysipPath) with open(sippysipAgentPath, 'wb') as na: na.write(sippySIPAgentScript) with open(sippysipLAPath, 'wb') as la: la.write(sippySIPLaunchAgent) # Turn on sippysip's agent SippySIPLog('Loading sippysip agent...') launchCTL('/bin/launchctl', 'asuser', userId, '/bin/launchctl', 'load', sippysipLAPath) # Wait for sippysip's agent to complete while not os.path.isfile(sippysipWatchPath): SippySIPLog('Waiting for the trigger file...') time.sleep(0.5) # Clean this shit up. SippySIPLog('Cleaning up sippysip agent folder and files...') cleanUp(sippysipPath, sippysipLAPath, sippysipLAId, userId, sippysipWatchPath)
forcecheck = True if forcecheck: updatelist = getAvailableUpdates() if updatelist: writeFilteredUpdateCatalog(updatelist) try: cacheSwupdMetadata() except ReplicationError, err: munkicommon.display_warning( 'Could not replicate software update metadata:') munkicommon.display_warning('\t', err) return False if downloadAvailableUpdates(): # Download success. Updates ready to install. munkicommon.set_pref('LastAppleSoftwareUpdateCheck', NSDate.date()) return True else: # Download error, allow check again soon. return False else: # No updates found (not currently differentiating # "softwareupdate -l" failure from no updates found). munkicommon.set_pref('LastAppleSoftwareUpdateCheck', NSDate.date()) return False else: munkicommon.log('Skipping Apple Software Update check because ' 'sucatalog is unchanged, installed Apple packages ' 'are unchanged and we recently did a full check') return False
def main(): # # UNIX command 'date' # if False: pr("UNIX command 'date'") cmd = 'date' r = commands.getoutput(cmd) pr("UNIX date command", r) pr("r.split()[4]", r.split()[4]) # # Python datetime # if False: pr("Python datetime") pr('datetime.datetime.now() ', datetime.datetime.now() ) t = datetime.datetime.now() - datetime.datetime.utcnow() pr("datetime.now() - datetime.utcnow()", t) pr("timedelta(-1, 68399, 999998) == timedelta(-1, 68400, 0)", datetime.timedelta(-1, 68399, 999998) == datetime.timedelta(-1, 68400, 0) ) pr("datetime.timedelta(hours=-5, seconds = -1) < t < datetime.timedelta(hours=-5, seconds = 1)", datetime.timedelta(hours=-5, seconds = -1) < t < datetime.timedelta(hours=-5, seconds = 1)) # print datetime.timedelta(hours=-5, seconds = 0) < t < datetime.timedelta(hours=-5, seconds = 1) #False # print datetime.timedelta(hours=-5, seconds = -1) < t < datetime.timedelta(hours=-5, seconds = 0) #True t2 = datetime.datetime.utcnow() + t pr('strftime("%a %Y.%m.%d %I:%M:%S")', t2.strftime("%a %Y.%m.%d %I:%M:%S") ) d3 = datetime.datetime(2011, 7, 29, 23, 46, 39) pr( 'str(d3)', str(d3) ) prr("_DATETIME_to_python(d3)", _DATETIME_to_python(d3)) # # Cocoa (Foundation) NSDate, NSCalendar, NSDateFormatter, etc. # pr("Cocoa (Foundation) NSDate, etc.") date1 = NSDate.dateWithTimeIntervalSinceReferenceDate_(333675999.713839) date2 = NSDate.dateWithTimeIntervalSinceReferenceDate_(333675999.713839 - 6 * 30 * 24 *60 * 60) date3 = NSDate.distantPast() # dateWithTimeIntervalSinceNow_(0- 6 * 30 * 24 *60 * 60) pr( "date1" , date1) pr( "date2" , date2) pr( "date3" , date3) prr("_DATETIME_to_python(date1)", _DATETIME_to_python(date1)) # pr( "str(date1) ", str(date1) ) currentCalendar = NSCalendar.currentCalendar() # # time zones # def pr_tz(l, tz): s = tz.secondsFromGMT() / (60 * 60) print "%s:\n\n %r (%s) offset %d hours%s\n" % (l,tz.name(), tz.abbreviation(), s , " (**local**)" if "Local Time Zone " in tz.description() else "") # print tz.description() # timeZone_Current = currentCalendar.timeZone() # # pr_tz('timeZone_Local', timeZone_Local) # # # s = timeZone_GMT.secondsFromGMT() / (60 * 60) # # pr("timeZone_GMT", str(timeZone_GMT) + " offset: %d hours" % s ) # pr( "timeZone_Local.isDaylightSavingTime()", timeZone_Local.isDaylightSavingTime() ) # determines whether daylight saving time is currently in effect. # pr( "timeZone_Local.daylightSavingTimeOffset()", timeZone_Local.daylightSavingTimeOffset() ) # determines the current daylight saving time offset. For most time zones this is either zero or one. # pr( "timeZone_Local.nextDaylightSavingTimeTransition()", timeZone_Local.nextDaylightSavingTimeTransition()) # Formatting for Machines: Controlled Environment Needed # # It is a whole other matter if you need to create a date string according to # the specification of a certain file format or API. # In such a case, you usually have to follow a very strict spec to # make sure the other party can read the string you are generating. # By default, NSDateFormatter uses the user’s current calendar and time zone, # which are possibly different from the requirements. # Most file formats and web APIs use the western, Gregorian calendar, # so we need to make sure that our date formatter uses it, too. dateFormatter_Local = NSDateFormatter.alloc().init() dateFormatter_Current = NSDateFormatter.alloc().init() dateFormatter_GMT = NSDateFormatter.alloc().init() dateFormatter_GMT5 = NSDateFormatter.alloc().init() dateFormatter_NY = NSDateFormatter.alloc().init() # dateFormatter_Local.__name__ = 'dateFormatter_Local' formatter_names = [ ] time_zones = [ ('Local' , NSTimeZone.localTimeZone()) , ('Current' , currentCalendar.timeZone()) , ('GMT' , NSTimeZone.timeZoneForSecondsFromGMT_(0)) , ('GMT5' , NSTimeZone.timeZoneForSecondsFromGMT_(-18000)) , ('NY' , NSTimeZone.timeZoneWithName_(u'America/New_York')) , ('System', NSTimeZone. systemTimeZone() ) , ('G' , NSTimeZone.timeZoneWithAbbreviation_(u'GMT')) ] dx = [ {'name' : n , 'tz' : tz, 'df' : NSDateFormatter.alloc().init() } for n, tz in time_zones ] s = [ "%12s: %s" % (x['name'], "%r (%s) %s%s" % tz_pr(x['tz']) ) for x in dx ] print "\n".join(s) print def eq_classes(dx, k): # z = [] d = {} for n, x in enumerate(dx): if x[k] not in d: d[x[k]] = set([ x['name'] ]) for m in range(n): y = dx[m] if x != y and x[k] == y[k]: # z.append((x['name'], y['name'])) if x[k] in d: d[x[k]].add( x['name'] ) # else: # d[x[k]] = set([ x['name'] ]) if y[k] in d: d[y[k]].add( y['name'] ) # else: # d[y[k]] = [ y['name'] ] return d print "eq_classes of dx (under tz):" print eq_classes_dx = eq_classes(dx, 'tz') print "\n".join([ "%20s: %s" % (x.name(), list(eq_classes_dx[x])) for x in eq_classes_dx]) print eq_names = [ list(eq_classes_dx[x])[0] for x in eq_classes_dx ] dx = [ z for z in dx if z['name'] in eq_names ] s = [ "%12s: %s" % (x['name'], "%r (%s) %s%s" % tz_pr(x['tz']) ) for x in dx ] print "\n".join(s) print # print "\n".join([ "%20s: %r" % [k for k in x] for x in dx ]) # format string (formatter) # format_string = "E yyyy'-'MM'-'dd' 'HH':'mm':'ss VVVV" # ==> "AD 2011-07-29 19:46:39 United States (New York)" # format_string = "E yyyy'-'MM'-'dd' 'HH':'mm':'ss VVV" # ==> " 'Fri 2011-07-29 19:46:39 GMT-04:00' format_string = "E yyyy'-'MM'-'dd' 'HH':'mm':'ss z" # ==> 'Fri 2011-07-29 19:46:39 EDT') or 'EST', or 'GMT-04:00' map ( lambda y : NSDateFormatter.setDateFormat_(y, format_string) , [x['df'] for x in dx] ) # locale locale = NSLocale.alloc().initWithLocaleIdentifier_("en_US_POSIX") pr("NSDate.date()", NSDate.date()) map ( lambda y : NSDateFormatter.setLocale_(y, locale) , [x['df'] for x in dx] ) map ( lambda y : NSDateFormatter.setTimeZone_(y[0], y[1]) , [ (x['df'], x['tz']) for x in dx] ) pr('descriptionWithCalendarFormat:timeZone:locale', date1.descriptionWithCalendarFormat_timeZone_locale_( None, None, locale) ) # format_string,NSTimeZone.timeZoneForSecondsFromGMT_(-18000),locale pr('descriptionWithCalendarFormat:timeZone:locale', date1.descriptionWithCalendarFormat_timeZone_locale_( None, NSTimeZone.timeZoneForSecondsFromGMT_(-18000), locale) ) # format_string,NSTimeZone.timeZoneForSecondsFromGMT_(-18000),locale for a in [date1, date2, date3]: dsd = get_datestrings(dx, a) s = [ "%12s: %r" % (x[0], x[1] ) for x in dsd ] print "\n".join(s) print # # date1_components # fcdc = currentCalendar.components_fromDate_( NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit , date1 ) pr( "currentCalendar.components_fromDate", [ fcdc.year(), fcdc.month(), fcdc.day(), fcdc.hour(), fcdc.minute(), fcdc.second(), ] ) dateOfKeynote = currentCalendar.dateFromComponents_(fcdc) pr( "currentCalendar.dateFromComponents", dateOfKeynote )
my_policy['com.oracle.java.JavaAppletPlugin'][ 'PlugInHostnamePolicies'] = NSMutableArray.alloc().initWithArray_( current_array) else: # create an empty array my_policy['com.oracle.java.JavaAppletPlugin'][ 'PlugInHostnamePolicies'] = [] found_foocorp_vpn = False # iterate through dicts in com.oracle.java.JavaAppletPlugin:PlugInHostnamePolicies for dict_item in my_policy['com.oracle.java.JavaAppletPlugin'][ 'PlugInHostnamePolicies']: if dict_item.get('PlugInHostname') == 'vpn.foocorp.com': found_foocorp_vpn = True if not found_foocorp_vpn: foocorp_vpn = { 'PlugInPageURL': 'https://vpn.foocorp.com/index.cgi', 'PlugInHostname': 'vpn.foocorp.com', 'PlugInRunUnsandboxed': True, 'PlugInPolicy': 'PlugInPolicyAllowNoSecurityRestrictions', 'PlugInLastVisitedDate': NSDate.date() } # add our new policy to the array my_policy['com.oracle.java.JavaAppletPlugin'][ 'PlugInHostnamePolicies'].append(foocorp_vpn) # save the changed preference CoreFoundation.CFPreferencesSetAppValue("ManagedPlugInPolicies", my_policy, "com.apple.Safari")
def last_modified(resp): """Return the last modified date as a unix time_t""" last_mod = _nsdf.dateFromString_(resp.headers.get('Last-Modified')) if not last_mod: last_mod = NSDate.date() return last_mod.timeIntervalSince1970()
print return print p.evaluateWithObject_(obj) print info = {} info['os_vers'] = '10.8.2' info['os_vers_patch'] = 2 info['arch'] = 'x86_64' info['munki_version'] = '0.8.3.1489.0' info['catalogs'] = ['testing', 'production'] info['ip_addresses'] = ['172.30.161.160', '172.30.157.57'] info['ip_address'] = '172.30.161.160' info['date'] = NSDate.date() info['machine_model'] = 'MacBookAir5,2' print info print predicate = 'NOT machine_model BEGINSWITH "MacBookAir"' doComparison(predicate, info) comparisonstring = 'nonexistent == nil' doComparison(comparisonstring, info) comparisonstring = 'machine_model LIKE "*Book*"' doComparison(comparisonstring, info) comparisonstring = 'date > CAST("2013-01-02T00:00:00Z", "NSDate")'
App Icon Design by: FIF7Y Code License: New BSD License This software will always be free of charge. Donations can be done via the website and will be much appreciated. """ updateText = "There is a new version of BtBatStat Available." appUrl = 'http://code.google.com/p/btbatstat/' updateUrl = 'http://code.google.com/p/btbatstat/downloads/list' parser = OptionParser() parser.add_option("-d", action="store_true", dest="debug") (options, args)= parser.parse_args() start_time = NSDate.date() def versionCheck(): try: LatestRelease = urllib2.urlopen("http://btbatstat.vandalon.org/VERSION", None, 2).read().strip() except: return False return ( LatestRelease and map(int, LatestRelease.split('.')) > map(int, VERSION.split('.')) ) #Check for new version def checkForUpdates(): if versionCheck(): if NSRunAlertPanel(LONGVERSION, updateText , "Download Update", "Ignore for now", None ) == 1: webbrowser.open(updateUrl) class Timer(NSObject):
def force_install_package_check(): """Check installable packages and applicable Apple updates for force install parameters. This method modifies InstallInfo and/or AppleUpdates in one scenario: It enables the unattended_install flag on all packages which need to be force installed and do not have a RestartAction. The return value may be one of: 'now': a force install is about to occur 'soon': a force install will occur within FORCE_INSTALL_WARNING_HOURS 'logout': a force install is about to occur and requires logout 'restart': a force install is about to occur and requires restart None: no force installs are about to occur """ result = None managed_install_dir = prefs.pref('ManagedInstallDir') installinfo_types = { 'InstallInfo.plist': 'managed_installs', 'AppleUpdates.plist': 'AppleUpdates' } now = NSDate.date() now_xhours = NSDate.dateWithTimeIntervalSinceNow_( FORCE_INSTALL_WARNING_HOURS * 3600) for installinfo_plist in installinfo_types: pl_dict = installinfo_types[installinfo_plist] installinfopath = os.path.join(managed_install_dir, installinfo_plist) try: installinfo = FoundationPlist.readPlist(installinfopath) except FoundationPlist.NSPropertyListSerializationException: continue writeback = False for i in xrange(len(installinfo.get(pl_dict, []))): install = installinfo[pl_dict][i] force_install_after_date = install.get('force_install_after_date') if not force_install_after_date: continue force_install_after_date = ( info.subtract_tzoffset_from_date(force_install_after_date)) display.display_debug1('Forced install for %s at %s', install['name'], force_install_after_date) if now >= force_install_after_date: result = 'now' if install.get('RestartAction'): if install['RestartAction'] == 'RequireLogout': result = 'logout' elif (install['RestartAction'] == 'RequireRestart' or install['RestartAction'] == 'RecommendRestart'): result = 'restart' elif not install.get('unattended_install', False): display.display_debug1('Setting unattended install for %s', install['name']) install['unattended_install'] = True installinfo[pl_dict][i] = install writeback = True if not result and now_xhours >= force_install_after_date: result = 'soon' if writeback: FoundationPlist.writePlist(installinfo, installinfopath) return result
def alert(self, title, subtitle, message, delay=0, sound=False, userInfo={}): self.notification.setTitle_(title) self.notification.setSubtitle_(subtitle) self.notification.setInformativeText_(message) self.notification.setDeliveryDate_(NSDate.dateWithTimeInterval_sinceDate_(delay, NSDate.date())) # self.notification.setUserInfo_(userInfo) if sound: self.notification.setSoundName_("NSUserNotificationDefaultSoundName") NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(self.notification)