Rename notifier to munki-notifier

This commit is contained in:
Greg Neagle
2017-02-24 08:09:47 -08:00
parent cd33a20244
commit d241bd570b
11 changed files with 64 additions and 216 deletions

View File

@@ -144,7 +144,7 @@ class MSCAppDelegate(NSObject):
'''User clicked on a Notification Center alert'''
user_info = notification.userInfo()
if user_info.get('action') == 'open_url':
url = user_info.get('value')
url = user_info.get('value', 'munki://updates')
msclog.log("MSU", "Got user notification to open %s" % url)
self.openMunkiURL(url)
center.removeDeliveredNotification_(notification)

View File

@@ -9,30 +9,26 @@
/* Begin PBXBuildFile section */
C0022FD61AD9BCED007DCEC3 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0022FD51AD9BCED007DCEC3 /* Cocoa.framework */; };
C0022FDF1AD9BCED007DCEC3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C0022FDE1AD9BCED007DCEC3 /* main.m */; };
C0022FE21AD9BCED007DCEC3 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = C0022FE01AD9BCED007DCEC3 /* Credits.rtf */; };
C0022FE71AD9BCED007DCEC3 /* main.py in Resources */ = {isa = PBXBuildFile; fileRef = C0022FE61AD9BCED007DCEC3 /* main.py */; };
C0022FE91AD9BCED007DCEC3 /* AppDelegate.py in Resources */ = {isa = PBXBuildFile; fileRef = C0022FE81AD9BCED007DCEC3 /* AppDelegate.py */; };
C0022FEC1AD9BCED007DCEC3 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = C0022FEA1AD9BCED007DCEC3 /* MainMenu.xib */; };
C0022FEE1AD9BCED007DCEC3 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C0022FED1AD9BCED007DCEC3 /* Images.xcassets */; };
C01D0DC51E5CAE60002A2EE1 /* libpython2.6.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C01D0DC41E5CAE60002A2EE1 /* libpython2.6.dylib */; };
C0CC76561ADF416F0001FFF9 /* ncdb.py in Resources */ = {isa = PBXBuildFile; fileRef = C0CC76551ADF416F0001FFF9 /* ncdb.py */; };
C059327F1E5E3BA700BAFB16 /* libpython2.7.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C059327E1E5E3BA700BAFB16 /* libpython2.7.dylib */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
C0022FD21AD9BCED007DCEC3 /* notifier.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = notifier.app; sourceTree = BUILT_PRODUCTS_DIR; };
C0022FD21AD9BCED007DCEC3 /* munki-notifier.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "munki-notifier.app"; sourceTree = BUILT_PRODUCTS_DIR; };
C0022FD51AD9BCED007DCEC3 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
C0022FD81AD9BCED007DCEC3 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
C0022FD91AD9BCED007DCEC3 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
C0022FDA1AD9BCED007DCEC3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
C0022FDD1AD9BCED007DCEC3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C0022FDE1AD9BCED007DCEC3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
C0022FE11AD9BCED007DCEC3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
C0022FE61AD9BCED007DCEC3 /* main.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = main.py; sourceTree = "<group>"; };
C0022FE81AD9BCED007DCEC3 /* AppDelegate.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = AppDelegate.py; sourceTree = "<group>"; };
C0022FEB1AD9BCED007DCEC3 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; };
C0022FED1AD9BCED007DCEC3 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
C01D0DC41E5CAE60002A2EE1 /* libpython2.6.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpython2.6.dylib; path = ../../../../../../../../System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/config/libpython2.6.dylib; sourceTree = "<group>"; };
C0CC76551ADF416F0001FFF9 /* ncdb.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = ncdb.py; sourceTree = "<group>"; };
C059327E1E5E3BA700BAFB16 /* libpython2.7.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpython2.7.dylib; path = ../../../../../../../../System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config/libpython2.7.dylib; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -41,7 +37,7 @@
buildActionMask = 2147483647;
files = (
C0022FD61AD9BCED007DCEC3 /* Cocoa.framework in Frameworks */,
C01D0DC51E5CAE60002A2EE1 /* libpython2.6.dylib in Frameworks */,
C059327F1E5E3BA700BAFB16 /* libpython2.7.dylib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -51,7 +47,7 @@
C0022FC91AD9BCED007DCEC3 = {
isa = PBXGroup;
children = (
C0022FDB1AD9BCED007DCEC3 /* notifier */,
C0022FDB1AD9BCED007DCEC3 /* munki-notifier */,
C0022FD41AD9BCED007DCEC3 /* Frameworks */,
C0022FD31AD9BCED007DCEC3 /* Products */,
);
@@ -60,7 +56,7 @@
C0022FD31AD9BCED007DCEC3 /* Products */ = {
isa = PBXGroup;
children = (
C0022FD21AD9BCED007DCEC3 /* notifier.app */,
C0022FD21AD9BCED007DCEC3 /* munki-notifier.app */,
);
name = Products;
sourceTree = "<group>";
@@ -84,7 +80,7 @@
name = "Other Frameworks";
sourceTree = "<group>";
};
C0022FDB1AD9BCED007DCEC3 /* notifier */ = {
C0022FDB1AD9BCED007DCEC3 /* munki-notifier */ = {
isa = PBXGroup;
children = (
C0022FE61AD9BCED007DCEC3 /* main.py */,
@@ -93,9 +89,8 @@
C0022FED1AD9BCED007DCEC3 /* Images.xcassets */,
C0022FE31AD9BCED007DCEC3 /* SharedLibraries */,
C0022FDC1AD9BCED007DCEC3 /* Supporting Files */,
C0CC76551ADF416F0001FFF9 /* ncdb.py */,
);
path = notifier;
path = "munki-notifier";
sourceTree = "<group>";
};
C0022FDC1AD9BCED007DCEC3 /* Supporting Files */ = {
@@ -103,7 +98,6 @@
children = (
C0022FDD1AD9BCED007DCEC3 /* Info.plist */,
C0022FDE1AD9BCED007DCEC3 /* main.m */,
C0022FE01AD9BCED007DCEC3 /* Credits.rtf */,
);
name = "Supporting Files";
sourceTree = "<group>";
@@ -111,7 +105,7 @@
C0022FE31AD9BCED007DCEC3 /* SharedLibraries */ = {
isa = PBXGroup;
children = (
C01D0DC41E5CAE60002A2EE1 /* libpython2.6.dylib */,
C059327E1E5E3BA700BAFB16 /* libpython2.7.dylib */,
);
name = SharedLibraries;
sourceTree = "<group>";
@@ -119,9 +113,9 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
C0022FD11AD9BCED007DCEC3 /* notifier */ = {
C0022FD11AD9BCED007DCEC3 /* munki-notifier */ = {
isa = PBXNativeTarget;
buildConfigurationList = C0022FF11AD9BCED007DCEC3 /* Build configuration list for PBXNativeTarget "notifier" */;
buildConfigurationList = C0022FF11AD9BCED007DCEC3 /* Build configuration list for PBXNativeTarget "munki-notifier" */;
buildPhases = (
C0022FCE1AD9BCED007DCEC3 /* Sources */,
C0022FCF1AD9BCED007DCEC3 /* Frameworks */,
@@ -132,9 +126,9 @@
);
dependencies = (
);
name = notifier;
name = "munki-notifier";
productName = notifier;
productReference = C0022FD21AD9BCED007DCEC3 /* notifier.app */;
productReference = C0022FD21AD9BCED007DCEC3 /* munki-notifier.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
@@ -151,7 +145,7 @@
};
};
};
buildConfigurationList = C0022FCD1AD9BCED007DCEC3 /* Build configuration list for PBXProject "notifier" */;
buildConfigurationList = C0022FCD1AD9BCED007DCEC3 /* Build configuration list for PBXProject "munki-notifier" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
@@ -163,7 +157,7 @@
projectDirPath = "";
projectRoot = "";
targets = (
C0022FD11AD9BCED007DCEC3 /* notifier */,
C0022FD11AD9BCED007DCEC3 /* munki-notifier */,
);
};
/* End PBXProject section */
@@ -173,10 +167,8 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C0022FE21AD9BCED007DCEC3 /* Credits.rtf in Resources */,
C0022FEE1AD9BCED007DCEC3 /* Images.xcassets in Resources */,
C0022FE91AD9BCED007DCEC3 /* AppDelegate.py in Resources */,
C0CC76561ADF416F0001FFF9 /* ncdb.py in Resources */,
C0022FE71AD9BCED007DCEC3 /* main.py in Resources */,
C0022FEC1AD9BCED007DCEC3 /* MainMenu.xib in Resources */,
);
@@ -213,14 +205,6 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
C0022FE01AD9BCED007DCEC3 /* Credits.rtf */ = {
isa = PBXVariantGroup;
children = (
C0022FE11AD9BCED007DCEC3 /* en */,
);
name = Credits.rtf;
sourceTree = "<group>";
};
C0022FEA1AD9BCED007DCEC3 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
@@ -329,14 +313,15 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = notifier/Info.plist;
INFOPLIST_FILE = "munki-notifier/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(SYSTEM_LIBRARY_DIR)/Frameworks/Python.framework/Versions/2.6/lib/python2.6/config",
"$(SYSTEM_LIBRARY_DIR)/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config",
);
PRODUCT_NAME = "$(TARGET_NAME)";
MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_NAME = "munki-notifier";
};
name = Debug;
};
@@ -345,21 +330,22 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = notifier/Info.plist;
INFOPLIST_FILE = "munki-notifier/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(SYSTEM_LIBRARY_DIR)/Frameworks/Python.framework/Versions/2.6/lib/python2.6/config",
"$(SYSTEM_LIBRARY_DIR)/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config",
);
PRODUCT_NAME = "$(TARGET_NAME)";
MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_NAME = "munki-notifier";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
C0022FCD1AD9BCED007DCEC3 /* Build configuration list for PBXProject "notifier" */ = {
C0022FCD1AD9BCED007DCEC3 /* Build configuration list for PBXProject "munki-notifier" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C0022FEF1AD9BCED007DCEC3 /* Debug */,
@@ -368,7 +354,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C0022FF11AD9BCED007DCEC3 /* Build configuration list for PBXNativeTarget "notifier" */ = {
C0022FF11AD9BCED007DCEC3 /* Build configuration list for PBXNativeTarget "munki-notifier" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C0022FF21AD9BCED007DCEC3 /* Debug */,

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# AppDelegate.py
# notifier
# munki-notifier
#
# Created by Greg Neagle on 4/11/15.
# Copyright (c) 2015-2017 The Munki Project. All rights reserved.
@@ -17,15 +17,14 @@ from AppKit import *
import objc
#import ncdb
MSCbundleIdentifier = u'com.googlecode.munki.ManagedSoftwareCenter'
NotificationCenterUIBundleID = u'com.apple.notificationcenterui'
MSCBUNDLEIDENTIFIER = u'com.googlecode.munki.ManagedSoftwareCenter'
NOTIFICATIONCENTERBUNDLEID = u'com.apple.notificationcenterui'
def convertDictionary(a_dict):
'''Converts a python dictionary to a more native-ish NSDictionary containing NSStrings'''
# convert all our strings to native NSStrings to avoid this:
# convert all our strings to native NSStrings to avoid this on Sierra+:
# "Class 'OC_PythonDictionary' has a superclass that supports secure
# coding, but 'OC_PythonDictionary' overrides -initWithCoder: and does
# not override +supportsSecureCoding. The class must implement
@@ -39,7 +38,9 @@ def convertDictionary(a_dict):
class AppDelegate(NSObject):
'''NSApplication delegate'''
def applicationDidFinishLaunching_(self, notification):
'''React to app launch'''
nc = NSUserNotificationCenter.defaultUserNotificationCenter()
nc.setDelegate_(self)
@@ -51,37 +52,32 @@ class AppDelegate(NSObject):
return
else:
# can we post a Notification Center notification?
print "Starting up"
runningProcesses = NSWorkspace.sharedWorkspace(
).runningApplications().valueForKey_('bundleIdentifier')
if NotificationCenterUIBundleID in runningProcesses:
print "Gonna post a notification"
self.notify('Important updates pending', '', 'Due by 04/30/2015.',
'munki://updates')
if NOTIFICATIONCENTERBUNDLEID in runningProcesses:
# Notification Center is running, OK to notify
self.notify('Software updates available',
text='Some updates have been pending for more than 3 days',
url='munki://updates')
return
# Notification center is not available; just launch MSC.app and show updates
url = NSURL.URLWithString_('munki://updates')
NSWorkspace.sharedWorkspace(
).openURLs_withAppBundleIdentifier_options_additionalEventParamDescriptor_launchIdentifiers_(
[url], MSCbundleIdentifier, 0, None, None)
NSWorkspace.sharedWorkspace().openURL_(NSURL.URLWithString_('munki://updates'))
NSApp.terminate_(self)
def notify(self, title, subtitle, text, url):
def notify(self, title='', subtitle='', text='', url=''):
'''Send our notification'''
print "Entered notify"
notification = NSUserNotification.alloc().init()
print "Created notification"
notification.setTitle_(title)
if subtitle:
notification.setSubtitle_(subtitle)
if text:
notification.setInformativeText_(text)
notification.setSoundName_('NSUserNotificationDefaultSoundName')
user_info = convertDictionary({'sender': MSCbundleIdentifier,
'action': 'open_url',
'url': url,
'type': 'updates'})
notification.setUserInfo_(user_info)
if url:
user_info = convertDictionary({'action': 'open_url',
'value': url,
'type': 'updates'})
notification.setUserInfo_(user_info)
notification.setHasActionButton_(True)
notification.setActionButtonTitle_('Details')
# attempt to do notifications of alert style by default
@@ -91,39 +87,35 @@ class AppDelegate(NSObject):
# remove previously delivered notifications so we don't have multiple
# update notifications in Notification Center
nc.removeAllDeliveredNotifications()
print "Scheduling notification"
nc.scheduleNotification_(notification)
# send our notification on its way
nc.deliverNotification_(notification)
#def userNotificationCenter_didActivateNotification_(self, center, notification):
# '''User clicked on our notification'''
# print 'Got userNotificationCenter:didActivateNotification:'
# self.userActivatedNotification_(notification)
def userNotificationCenter_didActivateNotification_(self, center, notification):
'''User clicked on our notification'''
self.userActivatedNotification_(notification)
NSApp.terminate_(self)
def userNotificationCenter_shouldPresentNotification_(self, center, notification):
'''Delegate method called when Notification Center has decided it doesn't
need to present the notification -- returning True overrides that decision'''
print 'Got userNotificationCenter:shouldPresentNotification:'
return True
def userNotificationCenter_didDeliverNotification_(self, center, notification):
'''Notification was delivered and we can exit'''
print 'Got userNotificationCenter:didDeliverNotification:'
NSApp.terminate_(self)
def userActivatedNotification_(self, notification):
'''React to user clicking on notification by launching MSC.app and showing Updates page'''
'''React to user clicking on notification by opening a URL or by launching MSC.app and
showing Updates page'''
NSUserNotificationCenter.defaultUserNotificationCenter().removeDeliveredNotification_(
notification)
user_info = notification.userInfo()
if user_info and user_info.get('action') == 'open_url':
url = user_info.get('url')
NSWorkspace.sharedWorkspace(
).openURLs_withAppBundleIdentifier_options_additionalEventParamDescriptor_launchIdentifiers_(
[NSURL.URLWithString_(url)], MSCbundleIdentifier, 0, None, None)
url = user_info.get('value', 'munki://updates')
NSWorkspace.sharedWorkspace().openURL_(NSURL.URLWithString_(url))
else:
NSWorkspace.sharedWorkspace(
).openURLs_withAppBundleIdentifier_options_additionalEventParamDescriptor_launchIdentifiers_(
[NSURL.URLWithString_('munki://updates')], MSCbundleIdentifier, 0, None, None)
# just fall back to our default behavior, which is to show MSC updates
NSWorkspace.sharedWorkspace().openURL_(NSURL.URLWithString_('munki://updates'))
def swizzle(*args):
@@ -168,7 +160,7 @@ def swizzled_bundleIdentifier(self, original):
"""
if self == NSBundle.mainBundle():
# return our fake bundle identifier
return MSCbundleIdentifier
return MSCBUNDLEIDENTIFIER
else:
# call original function
return original(self)

View File

@@ -1,23 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment version="1060" identifier="macosx"/>
<deployment version="1080" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication"/>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application">
<customObject id="-3" userLabel="Application" customClass="NSObject">
<connections>
<outlet property="delegate" destination="373" id="374"/>
</connections>
</customObject>
<menu title="AMainMenu" systemMenu="main" id="29" userLabel="MainMenu">
<items>
<menuItem title="notifier" id="56">
<menu key="submenu" title="notifier" systemMenu="apple" id="57">
<menuItem title="munki-notifier" id="56">
<menu key="submenu" title="munki-notifier" systemMenu="apple" id="57">
<items>
<menuItem title="About notifier" id="58">
<menuItem title="About munki-notifier" id="58">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
@@ -32,7 +32,7 @@
<menuItem isSeparatorItem="YES" id="144">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Hide notifier" keyEquivalent="h" id="134">
<menuItem title="Hide munki-notifier" keyEquivalent="h" id="134">
<connections>
<action selector="hide:" target="-1" id="367"/>
</connections>
@@ -51,7 +51,7 @@
<menuItem isSeparatorItem="YES" id="149">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Quit notifier" keyEquivalent="q" id="136" userLabel="1111">
<menuItem title="Quit munki-notifier" keyEquivalent="q" id="136" userLabel="1111">
<connections>
<action selector="terminate:" target="-1" id="369"/>
</connections>
@@ -62,7 +62,7 @@
<menuItem title="Help" id="103" userLabel="1">
<menu key="submenu" title="Help" id="106" userLabel="2">
<items>
<menuItem title="notifier Help" keyEquivalent="?" id="111">
<menuItem title="munki-notifier Help" keyEquivalent="?" id="111">
<connections>
<action selector="showHelp:" target="-1" id="360"/>
</connections>

View File

@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# main.py
# notifier
# munki-notifier
#
# Created by Greg Neagle on 4/11/15.
# Copyright (c) 2015 The Munki Project. All rights reserved.

View File

@@ -1,29 +0,0 @@
{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
{\colortbl;\red255\green255\blue255;}
\paperw9840\paperh8400
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\b\fs24 \cf0 Engineering:
\b0 \
Some people\
\
\b Human Interface Design:
\b0 \
Some other people\
\
\b Testing:
\b0 \
Hopefully not nobody\
\
\b Documentation:
\b0 \
Whoever\
\
\b With special thanks to:
\b0 \
Mom\
}

View File

@@ -1,101 +0,0 @@
# -*- coding: utf-8 -*-
#
# ncdb.py
# notifier
#
# Created by Greg Neagle on 4/15/15.
# Copyright (c) 2015 The Munki Project. All rights reserved.
#
from glob import glob
import os
import subprocess
import sqlite3
def get_nc_db():
'''Returns a path to the current (hopefully?) NotificationCenter db'''
nc_db = None
# try DARWIN_USER_DIR location first
cmd = ['/usr/bin/getconf', 'DARWIN_USER_DIR']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, err = proc.communicate()
darwin_user_dir = output.rstrip()
nc_db = os.path.join(darwin_user_dir, 'com.apple.notificationcenter/db/db')
if os.path.exists(nc_db):
return nc_db
# try the 'old' path
nc_nb_path = os.path.expanduser(
'~/Library/Application Support/NotificationCenter/')
nc_dbs = glob(nc_nb_path + '*.db')
if nc_dbs:
nc_dbs.sort(key=os.path.getmtime)
# most recently modified will be the last one
nc_db = nc_dbs[-1]
return nc_db
def connect_to_db():
'''Connect to the Notification Center db and return connection object
and cursor'''
conn = None
curs = None
#Connect To SQLLite
nc_db = get_nc_db()
if nc_db:
conn = sqlite3.connect(nc_db)
conn.text_factory = str
curs = conn.cursor()
return conn, curs
def bundleid_exists(bundle_id):
'''Returns a boolean telling us if the bundle_id is in the database.'''
conn, curs = connect_to_db()
curs.execute("SELECT bundleid from app_info WHERE bundleid IS '%s'"
% bundle_id)
matching_ids = [row[0] for row in curs.fetchall()]
conn.close()
return len(matching_ids) > 0
# flags are bits in a 16 bit(?) data structure
DONT_SHOW_IN_CENTER = 1 << 0
BADGE_ICONS = 1 << 1
SOUNDS = 1 << 2
BANNER_STYLE = 1 << 3
ALERT_STYLE = 1 << 4
UNKNOWN_5 = 1 << 5
UNKNOWN_6 = 1 << 6
UNKNOWN_7 = 1 << 7
UNKNOWN_8 = 1 << 8
UNKNOWN_9 = 1 << 9
UNKNOWN_10 = 1 << 10
UNKNOWN_11 = 1 << 11
SUPPRESS_NOTIFICATIONS_ON_LOCKSCREEN = 1 << 12
SHOW_PREVIEWS_ALWAYS = 1 << 13
SUPPRESS_MESSAGE_PREVIEWS = 1 << 14
UNKNOWN_15 = 1 << 15
def get_flags(bundle_id):
'''Returns flags for bundle_id'''
conn, curs = connect_to_db()
curs.execute("SELECT flags from app_info where bundleid='%s'" % (bundle_id))
try:
flags = curs.fetchall()[0][0]
except IndexError:
flags = 0
conn.close()
return int(flags)
def get_alert_style(bundle_id):
'''Get the alert style for bundle_id'''
current_flags = get_flags(bundle_id)
if current_flags & ALERT_STYLE:
return "alerts"
elif current_flags & BANNER_STYLE:
return "banners"
else:
return "none"