New munki-notifier

This commit is contained in:
Greg Neagle
2017-02-25 16:09:10 -08:00
parent 789bbc4e8e
commit 79b06d93e4
47 changed files with 1268 additions and 418 deletions
@@ -7,219 +7,288 @@
objects = {
/* 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 */; };
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 */; };
C059327F1E5E3BA700BAFB16 /* libpython2.7.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C059327E1E5E3BA700BAFB16 /* libpython2.7.dylib */; };
C081D8B91E5F4F5E00323D9C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C081D8B81E5F4F5E00323D9C /* AppDelegate.m */; };
C081D8BC1E5F4F5E00323D9C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C081D8BB1E5F4F5E00323D9C /* main.m */; };
C081D8BE1E5F4F5E00323D9C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C081D8BD1E5F4F5E00323D9C /* Assets.xcassets */; };
C081D8C11E5F4F5E00323D9C /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = C081D8BF1E5F4F5E00323D9C /* MainMenu.xib */; };
C081D8C91E5F5F2500323D9C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C081D8C81E5F5F2500323D9C /* Cocoa.framework */; };
C081D8CE1E60A82600323D9C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C081D8D01E60A82600323D9C /* Localizable.strings */; };
C081D8D41E60A82600323D9C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C081D8D61E60A82600323D9C /* InfoPlist.strings */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
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>"; };
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>"; };
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>"; };
C06BD1761E60B35800CB208E /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C06BD1771E60B35800CB208E /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
C06BD17B1E60B38900CB208E /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/MainMenu.strings; sourceTree = "<group>"; };
C081D8B41E5F4F5E00323D9C /* munki-notifier.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "munki-notifier.app"; sourceTree = BUILT_PRODUCTS_DIR; };
C081D8B71E5F4F5E00323D9C /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
C081D8B81E5F4F5E00323D9C /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
C081D8BB1E5F4F5E00323D9C /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
C081D8BD1E5F4F5E00323D9C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
C081D8C01E5F4F5E00323D9C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
C081D8C81E5F5F2500323D9C /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
C081D8CF1E60A82600323D9C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
C081D8D11E60A82600323D9C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/MainMenu.strings; sourceTree = "<group>"; };
C081D8D51E60A82600323D9C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C081D8D71E60A95000323D9C /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = "<group>"; };
C081D8D81E60A95000323D9C /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/MainMenu.strings; sourceTree = "<group>"; };
C081D8D91E60A95000323D9C /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C081D8DA1E60AAFA00323D9C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
C081D8DB1E60AAFA00323D9C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/MainMenu.strings; sourceTree = "<group>"; };
C081D8DC1E60AAFA00323D9C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C081D8DD1E60AC7300323D9C /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; };
C081D8DE1E60AC9200323D9C /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C0891D901E60B3C5001446D5 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C0891D911E60B3C5001446D5 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = "<group>"; };
C0891D961E60B3DA001446D5 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/MainMenu.strings; sourceTree = "<group>"; };
C0891D971E60B3F0001446D5 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C0891D981E60B3F0001446D5 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = "<group>"; };
C0891D9C1E60B3FD001446D5 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/MainMenu.strings; sourceTree = "<group>"; };
C0891D9D1E60B40A001446D5 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C0891D9E1E60B40A001446D5 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
C0891DA21E60B412001446D5 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/MainMenu.strings; sourceTree = "<group>"; };
C0891DAC1E60B43F001446D5 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/MainMenu.strings; sourceTree = "<group>"; };
C0891DAD1E60B44E001446D5 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
C0891DAE1E60B454001446D5 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C0891DAF1E60B473001446D5 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C0891DB01E60B473001446D5 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = "<group>"; };
C0891DB41E60B47C001446D5 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/MainMenu.strings; sourceTree = "<group>"; };
C0891DB81E60B49E001446D5 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/MainMenu.strings; sourceTree = "<group>"; };
C0891DB91E60B4D4001446D5 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C0891DBA1E60B4DE001446D5 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = "<group>"; };
C0891DBB1E60B4F1001446D5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C0891DBC1E60B4F1001446D5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; };
C0891DC01E60B518001446D5 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/MainMenu.strings; sourceTree = "<group>"; };
C0891DC11E60B527001446D5 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/InfoPlist.strings; sourceTree = "<group>"; };
C0891DC21E60B527001446D5 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = "<group>"; };
C0891DC61E60B535001446D5 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/MainMenu.strings; sourceTree = "<group>"; };
C0891DCB1E60B972001446D5 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = "munki-notifier/Info.plist"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
C0022FCF1AD9BCED007DCEC3 /* Frameworks */ = {
C081D8B11E5F4F5E00323D9C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C0022FD61AD9BCED007DCEC3 /* Cocoa.framework in Frameworks */,
C059327F1E5E3BA700BAFB16 /* libpython2.7.dylib in Frameworks */,
C081D8C91E5F5F2500323D9C /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
C0022FC91AD9BCED007DCEC3 = {
C081D8AB1E5F4F5E00323D9C = {
isa = PBXGroup;
children = (
C0022FDB1AD9BCED007DCEC3 /* munki-notifier */,
C0022FD41AD9BCED007DCEC3 /* Frameworks */,
C0022FD31AD9BCED007DCEC3 /* Products */,
C0891DCB1E60B972001446D5 /* Info.plist */,
C081D8CA1E5F5F5000323D9C /* Frameworks */,
C081D8B61E5F4F5E00323D9C /* munki-notifier */,
C081D8B51E5F4F5E00323D9C /* Products */,
);
sourceTree = "<group>";
};
C0022FD31AD9BCED007DCEC3 /* Products */ = {
C081D8B51E5F4F5E00323D9C /* Products */ = {
isa = PBXGroup;
children = (
C0022FD21AD9BCED007DCEC3 /* munki-notifier.app */,
C081D8B41E5F4F5E00323D9C /* munki-notifier.app */,
);
name = Products;
sourceTree = "<group>";
};
C0022FD41AD9BCED007DCEC3 /* Frameworks */ = {
C081D8B61E5F4F5E00323D9C /* munki-notifier */ = {
isa = PBXGroup;
children = (
C0022FD51AD9BCED007DCEC3 /* Cocoa.framework */,
C0022FD71AD9BCED007DCEC3 /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "<group>";
};
C0022FD71AD9BCED007DCEC3 /* Other Frameworks */ = {
isa = PBXGroup;
children = (
C0022FD81AD9BCED007DCEC3 /* AppKit.framework */,
C0022FD91AD9BCED007DCEC3 /* CoreData.framework */,
C0022FDA1AD9BCED007DCEC3 /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
};
C0022FDB1AD9BCED007DCEC3 /* munki-notifier */ = {
isa = PBXGroup;
children = (
C0022FE61AD9BCED007DCEC3 /* main.py */,
C0022FE81AD9BCED007DCEC3 /* AppDelegate.py */,
C0022FEA1AD9BCED007DCEC3 /* MainMenu.xib */,
C0022FED1AD9BCED007DCEC3 /* Images.xcassets */,
C0022FE31AD9BCED007DCEC3 /* SharedLibraries */,
C0022FDC1AD9BCED007DCEC3 /* Supporting Files */,
C081D8D61E60A82600323D9C /* InfoPlist.strings */,
C081D8D01E60A82600323D9C /* Localizable.strings */,
C081D8B71E5F4F5E00323D9C /* AppDelegate.h */,
C081D8B81E5F4F5E00323D9C /* AppDelegate.m */,
C081D8BD1E5F4F5E00323D9C /* Assets.xcassets */,
C081D8BF1E5F4F5E00323D9C /* MainMenu.xib */,
C081D8BA1E5F4F5E00323D9C /* Supporting Files */,
);
path = "munki-notifier";
sourceTree = "<group>";
};
C0022FDC1AD9BCED007DCEC3 /* Supporting Files */ = {
C081D8BA1E5F4F5E00323D9C /* Supporting Files */ = {
isa = PBXGroup;
children = (
C0022FDD1AD9BCED007DCEC3 /* Info.plist */,
C0022FDE1AD9BCED007DCEC3 /* main.m */,
C081D8BB1E5F4F5E00323D9C /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
C0022FE31AD9BCED007DCEC3 /* SharedLibraries */ = {
C081D8CA1E5F5F5000323D9C /* Frameworks */ = {
isa = PBXGroup;
children = (
C059327E1E5E3BA700BAFB16 /* libpython2.7.dylib */,
C081D8CB1E5F5F6A00323D9C /* Other Frameworks */,
C081D8C81E5F5F2500323D9C /* Cocoa.framework */,
);
name = SharedLibraries;
name = Frameworks;
sourceTree = "<group>";
};
C081D8CB1E5F5F6A00323D9C /* Other Frameworks */ = {
isa = PBXGroup;
children = (
);
name = "Other Frameworks";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
C0022FD11AD9BCED007DCEC3 /* munki-notifier */ = {
C081D8B31E5F4F5E00323D9C /* munki-notifier */ = {
isa = PBXNativeTarget;
buildConfigurationList = C0022FF11AD9BCED007DCEC3 /* Build configuration list for PBXNativeTarget "munki-notifier" */;
buildConfigurationList = C081D8C51E5F4F5E00323D9C /* Build configuration list for PBXNativeTarget "munki-notifier" */;
buildPhases = (
C0022FCE1AD9BCED007DCEC3 /* Sources */,
C0022FCF1AD9BCED007DCEC3 /* Frameworks */,
C0022FD01AD9BCED007DCEC3 /* Resources */,
C0A9C4551AF2E475002E86B2 /* Embeded revision number in version */,
C081D8B01E5F4F5E00323D9C /* Sources */,
C081D8B11E5F4F5E00323D9C /* Frameworks */,
C081D8B21E5F4F5E00323D9C /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "munki-notifier";
productName = notifier;
productReference = C0022FD21AD9BCED007DCEC3 /* munki-notifier.app */;
productName = "munki-notifier";
productReference = C081D8B41E5F4F5E00323D9C /* munki-notifier.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
C0022FCA1AD9BCED007DCEC3 /* Project object */ = {
C081D8AC1E5F4F5E00323D9C /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0620;
LastUpgradeCheck = 0730;
ORGANIZATIONNAME = "The Munki Project";
TargetAttributes = {
C0022FD11AD9BCED007DCEC3 = {
CreatedOnToolsVersion = 6.2;
C081D8B31E5F4F5E00323D9C = {
CreatedOnToolsVersion = 7.3.1;
};
};
};
buildConfigurationList = C0022FCD1AD9BCED007DCEC3 /* Build configuration list for PBXProject "munki-notifier" */;
buildConfigurationList = C081D8AF1E5F4F5E00323D9C /* Build configuration list for PBXProject "munki-notifier" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
es,
fi,
it,
ja,
fr,
nb,
nl,
ru,
sv,
);
mainGroup = C0022FC91AD9BCED007DCEC3;
productRefGroup = C0022FD31AD9BCED007DCEC3 /* Products */;
mainGroup = C081D8AB1E5F4F5E00323D9C;
productRefGroup = C081D8B51E5F4F5E00323D9C /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
C0022FD11AD9BCED007DCEC3 /* munki-notifier */,
C081D8B31E5F4F5E00323D9C /* munki-notifier */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
C0022FD01AD9BCED007DCEC3 /* Resources */ = {
C081D8B21E5F4F5E00323D9C /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C0022FEE1AD9BCED007DCEC3 /* Images.xcassets in Resources */,
C0022FE91AD9BCED007DCEC3 /* AppDelegate.py in Resources */,
C0022FE71AD9BCED007DCEC3 /* main.py in Resources */,
C0022FEC1AD9BCED007DCEC3 /* MainMenu.xib in Resources */,
C081D8BE1E5F4F5E00323D9C /* Assets.xcassets in Resources */,
C081D8D41E60A82600323D9C /* InfoPlist.strings in Resources */,
C081D8CE1E60A82600323D9C /* Localizable.strings in Resources */,
C081D8C11E5F4F5E00323D9C /* MainMenu.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
C0A9C4551AF2E475002E86B2 /* Embeded revision number in version */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Embeded revision number in version";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# add this number to Git revision index to get \"build\" number consistent with old SVN repo\nMAGICNUMBER=482\n\nBASEVERNUM=`/usr/libexec/PlistBuddy -c \"Print :CFBundleShortVersionString\" \"${INFOPLIST_FILE}\"`\n\n# Git isn't installed on 10.6 or earlier by default, so find it\nGIT=`which git`\nif [ \"$GIT\" == \"\" ] ; then\n# let's hope it's in /usr/local/bin\nif [ -x \"/usr/local/bin/git\" ] ; then\nGIT=/usr/local/bin/git\nfi\nfi\n\nif [ \"$GIT\" != \"\" ] ; then\n# generate a psuedo-svn revision number from the list of Git revisions\nGITREV=`$GIT log -n1 --format=\"%H\" -- ./`\nGITREVINDEX=`$GIT rev-list --count $GITREV`\nREV=$(($GITREVINDEX + $MAGICNUMBER))\n\n/usr/libexec/PlistBuddy -c \"Set :CFBundleShortVersionString $BASEVERNUM.$REV\" \"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\"\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $REV\" \"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\"\n/usr/libexec/PlistBuddy -c \"Set :GitRevision string $GITREV\" \"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\"\nfi";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
C0022FCE1AD9BCED007DCEC3 /* Sources */ = {
C081D8B01E5F4F5E00323D9C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C0022FDF1AD9BCED007DCEC3 /* main.m in Sources */,
C081D8BC1E5F4F5E00323D9C /* main.m in Sources */,
C081D8B91E5F4F5E00323D9C /* AppDelegate.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
C0022FEA1AD9BCED007DCEC3 /* MainMenu.xib */ = {
C081D8BF1E5F4F5E00323D9C /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
C0022FEB1AD9BCED007DCEC3 /* en */,
C081D8C01E5F4F5E00323D9C /* Base */,
C081D8D11E60A82600323D9C /* en */,
C081D8D81E60A95000323D9C /* da */,
C081D8DB1E60AAFA00323D9C /* de */,
C06BD17B1E60B38900CB208E /* es */,
C0891D961E60B3DA001446D5 /* fi */,
C0891D9C1E60B3FD001446D5 /* it */,
C0891DA21E60B412001446D5 /* ja */,
C0891DAC1E60B43F001446D5 /* fr */,
C0891DB41E60B47C001446D5 /* nb */,
C0891DB81E60B49E001446D5 /* nl */,
C0891DC01E60B518001446D5 /* ru */,
C0891DC61E60B535001446D5 /* sv */,
);
name = MainMenu.xib;
sourceTree = "<group>";
};
C081D8D01E60A82600323D9C /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
C081D8CF1E60A82600323D9C /* en */,
C081D8D71E60A95000323D9C /* da */,
C081D8DA1E60AAFA00323D9C /* de */,
C081D8DD1E60AC7300323D9C /* Base */,
C06BD1771E60B35800CB208E /* es */,
C0891D911E60B3C5001446D5 /* fi */,
C0891D981E60B3F0001446D5 /* it */,
C0891D9E1E60B40A001446D5 /* ja */,
C0891DAD1E60B44E001446D5 /* fr */,
C0891DB01E60B473001446D5 /* nb */,
C0891DBA1E60B4DE001446D5 /* nl */,
C0891DBC1E60B4F1001446D5 /* ru */,
C0891DC21E60B527001446D5 /* sv */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
C081D8D61E60A82600323D9C /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
C081D8D51E60A82600323D9C /* en */,
C081D8D91E60A95000323D9C /* da */,
C081D8DC1E60AAFA00323D9C /* de */,
C081D8DE1E60AC9200323D9C /* Base */,
C06BD1761E60B35800CB208E /* es */,
C0891D901E60B3C5001446D5 /* fi */,
C0891D971E60B3F0001446D5 /* it */,
C0891D9D1E60B40A001446D5 /* ja */,
C0891DAE1E60B454001446D5 /* fr */,
C0891DAF1E60B473001446D5 /* nb */,
C0891DB91E60B4D4001446D5 /* nl */,
C0891DBB1E60B4F1001446D5 /* ru */,
C0891DC11E60B527001446D5 /* sv */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
C0022FEF1AD9BCED007DCEC3 /* Debug */ = {
C081D8C31E5F4F5E00323D9C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
@@ -235,40 +304,35 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "-";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/System/Library/Frameworks/Python.framework/Versions/2.6/include/python2.6,
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(SYSTEM_LIBRARY_DIR)/Frameworks/Python.framework/Versions/2.6/lib/python2.6/config",
);
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
C0022FF01AD9BCED007DCEC3 /* Release */ = {
C081D8C41E5F4F5E00323D9C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
@@ -288,82 +352,67 @@
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/System/Library/Frameworks/Python.framework/Versions/2.6/include/python2.6,
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(SYSTEM_LIBRARY_DIR)/Frameworks/Python.framework/Versions/2.6/lib/python2.6/config",
);
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
};
name = Release;
};
C0022FF21AD9BCED007DCEC3 /* Debug */ = {
C081D8C61E5F4F5E00323D9C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
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",
);
MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_NAME = "munki-notifier";
MACOSX_DEPLOYMENT_TARGET = 10.6;
PRODUCT_BUNDLE_IDENTIFIER = "com.googlecode.munki.munki-notifier";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
C0022FF31AD9BCED007DCEC3 /* Release */ = {
C081D8C71E5F4F5E00323D9C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
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",
);
MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_NAME = "munki-notifier";
MACOSX_DEPLOYMENT_TARGET = 10.6;
PRODUCT_BUNDLE_IDENTIFIER = "com.googlecode.munki.munki-notifier";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
C0022FCD1AD9BCED007DCEC3 /* Build configuration list for PBXProject "munki-notifier" */ = {
C081D8AF1E5F4F5E00323D9C /* Build configuration list for PBXProject "munki-notifier" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C0022FEF1AD9BCED007DCEC3 /* Debug */,
C0022FF01AD9BCED007DCEC3 /* Release */,
C081D8C31E5F4F5E00323D9C /* Debug */,
C081D8C41E5F4F5E00323D9C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C0022FF11AD9BCED007DCEC3 /* Build configuration list for PBXNativeTarget "munki-notifier" */ = {
C081D8C51E5F4F5E00323D9C /* Build configuration list for PBXNativeTarget "munki-notifier" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C0022FF21AD9BCED007DCEC3 /* Debug */,
C0022FF31AD9BCED007DCEC3 /* Release */,
C081D8C61E5F4F5E00323D9C /* Debug */,
C081D8C71E5F4F5E00323D9C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = C0022FCA1AD9BCED007DCEC3 /* Project object */;
rootObject = C081D8AC1E5F4F5E00323D9C /* Project object */;
}
@@ -0,0 +1,12 @@
//
// AppDelegate.h
// munki-notifier
//
// Created by Greg Neagle on 2/23/17.
// Copyright © 2017 The Munki Project. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate, NSUserNotificationCenterDelegate>
@end
@@ -0,0 +1,255 @@
//
// AppDelegate.m
// munki-notifier
//
// Created by Greg Neagle on 2/23/17.
// Copyright © 2017 The Munki Project. All rights reserved.
// Much code lifted and adapted from https://github.com/julienXX/terminal-notifier
//
#import "AppDelegate.h"
#import <objc/runtime.h>
NSString * const MunkiNotifyBundleID = @"com.googlecode.munki.munki-notify";
NSString * const ManagedSoftwareCenterBundleID = @"com.googlecode.munki.ManagedSoftwareCenter";
NSString * const NotificationCenterUIBundleID = @"com.apple.notificationcenterui";
NSString * const MunkiUpdatesURL = @"munki://updates";
NSString *_fakeBundleIdentifier = nil;
@implementation NSBundle (FakeBundleIdentifier)
// Overriding bundleIdentifier works, but overriding NSUserNotificationAlertStyle does not work.
- (NSString *)__bundleIdentifier;
{
if (self == [NSBundle mainBundle]) {
return _fakeBundleIdentifier ? _fakeBundleIdentifier : MunkiNotifyBundleID;
} else {
return [self __bundleIdentifier];
}
}
@end
static BOOL
InstallFakeBundleIdentifierHook()
{
Class class = objc_getClass("NSBundle");
if (class) {
method_exchangeImplementations(
class_getInstanceMethod(class, @selector(bundleIdentifier)),
class_getInstanceMethod(class, @selector(__bundleIdentifier)));
return YES;
}
return NO;
}
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)notification;
{
NSUserNotification *userNotification = notification.userInfo[
NSApplicationLaunchUserNotificationKey];
if (userNotification) {
[self userActivatedNotification:userNotification];
[NSApp terminate: self];
} else {
// Do we have a running NotificationCenter?
NSArray *runningProcesses = [[[NSWorkspace sharedWorkspace] runningApplications]
valueForKey:@"bundleIdentifier"];
BOOL notificationCenterAvailable = ([runningProcesses indexOfObject:NotificationCenterUIBundleID]
!= NSNotFound);
if (notificationCenterAvailable) {
// Install the fake bundle ID hook so we can fake the sender. This also
// needs to be done to be able to remove a message.
@autoreleasepool {
if (InstallFakeBundleIdentifierHook()) {
_fakeBundleIdentifier = ManagedSoftwareCenterBundleID;
}
}
}
// get count of pending updates, oldest update days and any forced update due date
// from Munki's preferences
CFPropertyListRef plistRef = nil;
NSInteger updateCount = 0;
NSInteger oldestUpdateDays = 0;
NSDate *forcedUpdateDueDate = nil;
CFPreferencesAppSynchronize(CFSTR("ManagedInstalls"));
plistRef = CFPreferencesCopyValue(
CFSTR("PendingUpdateCount"), CFSTR("ManagedInstalls"), kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
if (plistRef && CFGetTypeID(plistRef) == CFNumberGetTypeID()) {
updateCount = [(NSNumber *)CFBridgingRelease(plistRef) integerValue];
}
plistRef = CFPreferencesCopyValue(
CFSTR("OldestUpdateDays"), CFSTR("ManagedInstalls"), kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
if (plistRef && CFGetTypeID(plistRef) == CFNumberGetTypeID()) {
oldestUpdateDays = [(NSNumber *)CFBridgingRelease(plistRef) integerValue];
}
plistRef = CFPreferencesCopyValue(
CFSTR("ForcedUpdateDueDate"), CFSTR("ManagedInstalls"), kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
if (plistRef && CFGetTypeID(plistRef) == CFDateGetTypeID()) {
forcedUpdateDueDate = (NSDate *)CFBridgingRelease((CFDateRef)plistRef);
}
if (updateCount == 0) {
// no available updates
if (notificationCenterAvailable) {
// clear any previously posted updates available notifications and exit
[[NSUserNotificationCenter defaultUserNotificationCenter] removeAllDeliveredNotifications];
}
[NSApp terminate: self];
return;
}
// updateCount > 0
if (! notificationCenterAvailable || oldestUpdateDays > 3) {
// Notification Center is not available or Notification Manager notifications
// are being ignored or suppressed; launch MSC.app and show updates
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString: MunkiUpdatesURL]];
[NSApp terminate: self];
return;
}
// We have Notification Center, create and post our notification
// Build a localized update count message
NSString *updateCountMessage = NSLocalizedString(@"1 pending update", @"One Update message");
NSString *multipleUpdatesFormatString = NSLocalizedString(
@"%@ pending updates", @"Multiple Update message");
if (updateCount > 1) {
updateCountMessage = [NSString stringWithFormat:multipleUpdatesFormatString,
[@(updateCount) stringValue]];
}
// Build a localized force install date message
NSString *deadlineMessage = nil;
NSString *deadlineMessageFormatString = NSLocalizedString(
@"One or more items must be installed by %@", @"Forced Install Date summary");
if (forcedUpdateDueDate) {
deadlineMessage = [NSString stringWithFormat:deadlineMessageFormatString,
[self stringFromDate: forcedUpdateDueDate]];
}
// Assemble all our needed notification info
NSString *title = NSLocalizedString(
@"Software updates available", @"Software updates available message");
NSString *subtitle = @"";
NSString *message = updateCountMessage;
if (deadlineMessage) {
subtitle = updateCountMessage;
message = deadlineMessage;
}
NSString *sound = @"default";
// Create options (userInfo) dictionary
NSMutableDictionary *options = [NSMutableDictionary dictionary];
options[@"groupID"] = @"com.googlecode.munki.munki-notifier.update-notification";
options[@"action"] = @"open_url";
options[@"value"] = MunkiUpdatesURL;
// deliver the notification
[self deliverNotificationWithTitle:title
subtitle:subtitle
message:message
options:options
sound:sound];
}
}
- (NSString *)stringFromDate:(NSDate *)date
{
NSDateFormatter *formatter = [NSDateFormatter new];
formatter.formatterBehavior = NSDateFormatterBehavior10_4;
formatter.dateStyle = NSDateFormatterShortStyle;
formatter.timeStyle = NSDateFormatterNoStyle;
formatter.doesRelativeDateFormatting = YES;
formatter.formattingContext = NSFormattingContextDynamic;
return [formatter stringFromDate:date];
}
- (void)deliverNotificationWithTitle:(NSString *)title
subtitle:(NSString *)subtitle
message:(NSString *)message
options:(NSDictionary *)options
sound:(NSString *)sound;
{
// First remove earlier notifications from us
[[NSUserNotificationCenter defaultUserNotificationCenter] removeAllDeliveredNotifications];
// this other way doesn't seem to work reliably.
//if (options[@"groupID"]) [self removeNotificationWithGroupID:options[@"groupID"]];
NSUserNotification *userNotification = [NSUserNotification new];
userNotification.title = title;
if (! [subtitle isEqualToString:@""]) userNotification.subtitle = subtitle;
if (! [message isEqualToString:@""]) userNotification.informativeText = message;
userNotification.userInfo = options;
// Attempt to display as alert style (though user can override at any time)
[userNotification setValue:@YES forKey:@"_showsButtons"];
userNotification.hasActionButton = true;
userNotification.actionButtonTitle = NSLocalizedString(@"Details", @"Details label");
if (sound != nil) {
userNotification.soundName = [sound isEqualToString: @"default"] ? NSUserNotificationDefaultSoundName : sound;
}
NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
center.delegate = self;
[center deliverNotification:userNotification];
}
// this function does not appear to reliably remove notifications. To further investigate in the future.
- (void)removeNotificationWithGroupID:(NSString *)groupID;
{
NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
for (NSUserNotification *userNotification in center.deliveredNotifications) {
if ([@"ALL" isEqualToString:groupID] || [userNotification.userInfo[@"groupID"] isEqualToString:groupID]) {
[center removeDeliveredNotification:userNotification];
}
}
}
// React to user clicking on notification
- (void)userActivatedNotification:(NSUserNotification *)userNotification;
{
[[NSUserNotificationCenter defaultUserNotificationCenter] removeDeliveredNotification:userNotification];
NSString *action = userNotification.userInfo[@"action"];
NSString *value = userNotification.userInfo[@"value"];
if ([action isEqualToString:@"open_url"]){
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:value]];
} else {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString: MunkiUpdatesURL]];
}
}
// Return YES to present the notification even if MSC.app is frontmost
- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center
shouldPresentNotification:(NSUserNotification *)notification;
{
return YES;
}
// Once the notification is delivered we can exit.
- (void)userNotificationCenter:(NSUserNotificationCenter *)center
didDeliverNotification:(NSUserNotification *)notification;
{
[NSApp terminate: self];
}
// handle user clicking on our notification
- (void)userNotificationCenter:(NSUserNotificationCenter *)center
didActivateNotification:(NSUserNotification *)notification
{
[self userActivatedNotification:notification];
[NSApp terminate: self];
}
@end
@@ -1,166 +0,0 @@
# -*- coding: utf-8 -*-
#
# AppDelegate.py
# munki-notifier
#
# Created by Greg Neagle on 4/11/15.
# Copyright (c) 2015-2017 The Munki Project. All rights reserved.
#
# Much inspiration from terminal-notifier
# https://github.com/alloy/terminal-notifier
#
import os
from Foundation import *
from AppKit import *
import objc
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 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
# +supportsSecureCoding and return YES"
new_dict = {}
for key, value in a_dict.items():
if isinstance(value, basestring):
value = NSString.stringWithString_(value)
new_dict[NSString.stringWithString_(key)] = value
return NSDictionary.dictionaryWithDictionary_(new_dict)
class AppDelegate(NSObject):
'''NSApplication delegate'''
def applicationDidFinishLaunching_(self, notification):
'''React to app launch'''
nc = NSUserNotificationCenter.defaultUserNotificationCenter()
nc.setDelegate_(self)
userNotification = notification.userInfo().get('NSApplicationLaunchUserNotificationKey')
if userNotification:
NSLog('%@', 'Launched due to NSUserNotification')
self.userActivatedNotification_(userNotification)
NSApp.terminate_(self)
return
else:
# can we post a Notification Center notification?
runningProcesses = NSWorkspace.sharedWorkspace(
).runningApplications().valueForKey_('bundleIdentifier')
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
NSWorkspace.sharedWorkspace().openURL_(NSURL.URLWithString_('munki://updates'))
NSApp.terminate_(self)
def notify(self, title='', subtitle='', text='', url=''):
'''Send our notification'''
notification = NSUserNotification.alloc().init()
notification.setTitle_(title)
if subtitle:
notification.setSubtitle_(subtitle)
if text:
notification.setInformativeText_(text)
notification.setSoundName_('NSUserNotificationDefaultSoundName')
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
# (unsupported private API!)
notification.setValue_forKey_(True, "_showsButtons")
nc = NSUserNotificationCenter.defaultUserNotificationCenter()
# remove previously delivered notifications so we don't have multiple
# update notifications in Notification Center
nc.removeAllDeliveredNotifications()
# send our notification on its way
nc.deliverNotification_(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'''
return True
def userNotificationCenter_didDeliverNotification_(self, center, notification):
'''Notification was delivered and we can exit'''
NSApp.terminate_(self)
def userActivatedNotification_(self, notification):
'''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('value', 'munki://updates')
NSWorkspace.sharedWorkspace().openURL_(NSURL.URLWithString_(url))
else:
# just fall back to our default behavior, which is to show MSC updates
NSWorkspace.sharedWorkspace().openURL_(NSURL.URLWithString_('munki://updates'))
def swizzle(*args):
"""
Decorator to override an ObjC selector's implementation with a
custom implementation ("method swizzling").
Use like this:
@swizzle(NSOriginalClass, 'selectorName')
def swizzled_selectorName(self, original):
--> `self` points to the instance
--> `original` is the original implementation
Originally from http://klep.name/programming/python/
(The link was dead on 2013-05-22 but the Google Cache version works:
http://goo.gl/ABGvJ)
"""
cls, SEL = args
def decorator(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)
return wrapper
return decorator
@swizzle(NSBundle, 'bundleIdentifier')
def swizzled_bundleIdentifier(self, original):
"""Swizzle [NSBundle bundleIdentifier] to post a notification as a different bundleID
Original idea for this approach by Norio Numura:
https://github.com/norio-nomura/usernotification
"""
if self == NSBundle.mainBundle():
# return our fake bundle identifier
return MSCBUNDLEIDENTIFIER
else:
# call original function
return original(self)
@@ -0,0 +1,3 @@
/* (No Commment) */
"NSHumanReadableCopyright" = "Copyright © 2017 The Munki Project. All rights reserved.";
@@ -0,0 +1,15 @@
/* Multiple Update message */
"%@ pending updates" = "%@ pending updates";
/* One Update message */
"1 pending update" = "1 pending update";
/* Details label */
"Details" = "Details";
/* Forced Install Date summary */
"One or more items must be installed by %@" = "One or more items must be installed by %@";
/* Software updates available message */
"Software updates available" = "Software updates available";
@@ -1,78 +1,84 @@
<?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">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment version="1080" identifier="macosx"/>
<deployment 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" customClass="NSObject">
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="373" id="374"/>
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
</connections>
</customObject>
<menu title="AMainMenu" systemMenu="main" id="29" userLabel="MainMenu">
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="munki-notifier" id="56">
<menu key="submenu" title="munki-notifier" systemMenu="apple" id="57">
<menuItem title="munki-notifier" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="munki-notifier" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About munki-notifier" id="58">
<menuItem title="About munki-notifier" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="236">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem title="Services" id="131">
<menu key="submenu" title="Services" systemMenu="services" id="130"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="144">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Hide munki-notifier" keyEquivalent="h" id="134">
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide munki-notifier" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="-1" id="367"/>
<action selector="hide:" target="-1" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="145">
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="-1" id="368"/>
<action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="150">
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="-1" id="370"/>
<action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="149">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Quit munki-notifier" keyEquivalent="q" id="136" userLabel="1111">
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit munki-notifier" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="-1" id="369"/>
<action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="103" userLabel="1">
<menu key="submenu" title="Help" id="106" userLabel="2">
<items>
<menuItem title="munki-notifier Help" keyEquivalent="?" id="111">
<connections>
<action selector="showHelp:" target="-1" id="360"/>
</connections>
</menuItem>
</items>
</menu>
<menuItem title="File" id="dMs-cI-mzQ">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Edit" id="5QF-Oa-p0T">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Format" id="jxT-CU-nIS">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="View" id="H8h-7b-M4v">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Help" id="wpr-3q-Mcd">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
</items>
</menu>
<customObject id="373" userLabel="AppDelegate" customClass="AppDelegate"/>
<customObject id="420" customClass="NSFontManager"/>
</objects>
</document>
@@ -4,8 +4,8 @@
<dict>
<key>NSUserNotificationAlertStyle</key>
<string>alert</string>
<key>GitRevision</key>
<string></string>
<key>LSUIElement</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
@@ -13,7 +13,7 @@
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.googlecode.munki.$(PRODUCT_NAME:rfc1034identifier)</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
@@ -28,10 +28,8 @@
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>LSUIElement</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2015-2017 The Munki Project. All rights reserved.</string>
<string>Copyright © 2017 The Munki Project. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
@@ -0,0 +1,3 @@
/* (No Commment) */
"NSHumanReadableCopyright" = "Copyright © 2017 The Munki Project. All rights reserved.";
@@ -0,0 +1,14 @@
/* Multiple Update message */
"%@ pending updates" = "%@ ventende opdateringer";
/* One Update message */
"1 pending update" = "1 ventende opdatering";
/* Details label */
"Details" = "Detaljer";
/* Forced Install Date summary */
"One or more items must be installed by %@" = "Et eller flere emner skal installeres senest %@";
/* Software updates available message */
"Software updates available" = "Softwareopdateringer til rådighed";
@@ -0,0 +1 @@
/* No Localized Strings */
@@ -0,0 +1,3 @@
/* (No Commment) */
"NSHumanReadableCopyright" = "Copyright © 2017 The Munki Project. All rights reserved.";
@@ -0,0 +1,15 @@
/* Multiple Update message */
"%@ pending updates" = "%@ anstehende Updates";
/* One Update message */
"1 pending update" = "1 anstehendes Update";
/* Details label */
"Details" = "Details";
/* Forced Install Date summary */
"One or more items must be installed by %@" = "Eines oder mehrere Objekte müssen bis %@ installiert werden.";
/* Software updates available message */
"Software updates available" = "Software-Updates verfügbar";
@@ -0,0 +1 @@
/* No Localized Strings */
@@ -0,0 +1,3 @@
/* (No Commment) */
"NSHumanReadableCopyright" = "Copyright © 2017 The Munki Project. All rights reserved.";
@@ -0,0 +1,15 @@
/* Multiple Update message */
"%@ pending updates" = "%@ pending updates";
/* One Update message */
"1 pending update" = "1 pending update";
/* Details label */
"Details" = "Details";
/* Forced Install Date summary */
"One or more items must be installed by %@" = "One or more items must be installed by %@";
/* Software updates available message */
"Software updates available" = "Software updates available";
@@ -0,0 +1,51 @@
/* Class = "NSMenuItem"; title = "munki-notifier"; ObjectID = "1Xt-HY-uBw"; */
"1Xt-HY-uBw.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Quit munki-notifier"; ObjectID = "4sb-4s-VLi"; */
"4sb-4s-VLi.title" = "Quit munki-notifier";
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */
"5QF-Oa-p0T.title" = "Edit";
/* Class = "NSMenuItem"; title = "About munki-notifier"; ObjectID = "5kV-Vb-QxS"; */
"5kV-Vb-QxS.title" = "About munki-notifier";
/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */
"AYu-sK-qS6.title" = "Main Menu";
/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */
"BOF-NM-1cW.title" = "Preferences…";
/* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */
"H8h-7b-M4v.title" = "View";
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */
"Kd2-mp-pUS.title" = "Show All";
/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */
"NMo-om-nkz.title" = "Services";
/* Class = "NSMenuItem"; title = "Hide munki-notifier"; ObjectID = "Olw-nP-bQN"; */
"Olw-nP-bQN.title" = "Hide munki-notifier";
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */
"Vdr-fp-XzO.title" = "Hide Others";
/* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */
"aUF-d1-5bR.title" = "Window";
/* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */
"dMs-cI-mzQ.title" = "File";
/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */
"hz9-B4-Xy5.title" = "Services";
/* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */
"jxT-CU-nIS.title" = "Format";
/* Class = "NSMenu"; title = "munki-notifier"; ObjectID = "uQy-DD-JDr"; */
"uQy-DD-JDr.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */
"wpr-3q-Mcd.title" = "Help";
@@ -0,0 +1,3 @@
/* (No Commment) */
"NSHumanReadableCopyright" = "Copyright © 2017 The Munki Project. All rights reserved.";
@@ -0,0 +1,15 @@
/* Multiple Update message */
"%@ pending updates" = "%@ actualizaciones pendiente";
/* One Update message */
"1 pending update" = "1 actualización pendiente";
/* Details label */
"Details" = "Detalles";
/* Forced Install Date summary */
"One or more items must be installed by %@" = "Una o mas applicaciones tiene que ser instalada para el %@";
/* Software updates available message */
"Software updates available" = "Actualizaciones de software disponibles";
@@ -0,0 +1,51 @@
/* Class = "NSMenuItem"; title = "munki-notifier"; ObjectID = "1Xt-HY-uBw"; */
"1Xt-HY-uBw.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Quit munki-notifier"; ObjectID = "4sb-4s-VLi"; */
"4sb-4s-VLi.title" = "Quit munki-notifier";
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */
"5QF-Oa-p0T.title" = "Edit";
/* Class = "NSMenuItem"; title = "About munki-notifier"; ObjectID = "5kV-Vb-QxS"; */
"5kV-Vb-QxS.title" = "About munki-notifier";
/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */
"AYu-sK-qS6.title" = "Main Menu";
/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */
"BOF-NM-1cW.title" = "Preferences…";
/* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */
"H8h-7b-M4v.title" = "View";
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */
"Kd2-mp-pUS.title" = "Show All";
/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */
"NMo-om-nkz.title" = "Services";
/* Class = "NSMenuItem"; title = "Hide munki-notifier"; ObjectID = "Olw-nP-bQN"; */
"Olw-nP-bQN.title" = "Hide munki-notifier";
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */
"Vdr-fp-XzO.title" = "Hide Others";
/* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */
"aUF-d1-5bR.title" = "Window";
/* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */
"dMs-cI-mzQ.title" = "File";
/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */
"hz9-B4-Xy5.title" = "Services";
/* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */
"jxT-CU-nIS.title" = "Format";
/* Class = "NSMenu"; title = "munki-notifier"; ObjectID = "uQy-DD-JDr"; */
"uQy-DD-JDr.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */
"wpr-3q-Mcd.title" = "Help";
@@ -0,0 +1,3 @@
/* (No Commment) */
"NSHumanReadableCopyright" = "Copyright © 2017 The Munki Project. All rights reserved.";
@@ -0,0 +1,15 @@
/* Multiple Update message */
"%@ pending updates" = "%@ päivitystä saatavilla";
/* One Update message */
"1 pending update" = "1 päivitys saatavilla";
/* Details label */
"Details" = "Lisätietoja";
/* Forced Install Date summary */
"One or more items must be installed by %@" = "Yksi tai useampi kohde täytyy asentaa ennen %@";
/* Software updates available message */
"Software updates available" = "Ohjelmistopäivityksiä saatavilla";
@@ -0,0 +1,51 @@
/* Class = "NSMenuItem"; title = "munki-notifier"; ObjectID = "1Xt-HY-uBw"; */
"1Xt-HY-uBw.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Quit munki-notifier"; ObjectID = "4sb-4s-VLi"; */
"4sb-4s-VLi.title" = "Quit munki-notifier";
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */
"5QF-Oa-p0T.title" = "Edit";
/* Class = "NSMenuItem"; title = "About munki-notifier"; ObjectID = "5kV-Vb-QxS"; */
"5kV-Vb-QxS.title" = "About munki-notifier";
/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */
"AYu-sK-qS6.title" = "Main Menu";
/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */
"BOF-NM-1cW.title" = "Preferences…";
/* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */
"H8h-7b-M4v.title" = "View";
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */
"Kd2-mp-pUS.title" = "Show All";
/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */
"NMo-om-nkz.title" = "Services";
/* Class = "NSMenuItem"; title = "Hide munki-notifier"; ObjectID = "Olw-nP-bQN"; */
"Olw-nP-bQN.title" = "Hide munki-notifier";
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */
"Vdr-fp-XzO.title" = "Hide Others";
/* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */
"aUF-d1-5bR.title" = "Window";
/* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */
"dMs-cI-mzQ.title" = "File";
/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */
"hz9-B4-Xy5.title" = "Services";
/* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */
"jxT-CU-nIS.title" = "Format";
/* Class = "NSMenu"; title = "munki-notifier"; ObjectID = "uQy-DD-JDr"; */
"uQy-DD-JDr.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */
"wpr-3q-Mcd.title" = "Help";
@@ -0,0 +1,3 @@
/* (No Commment) */
"NSHumanReadableCopyright" = "Copyright © 2017 The Munki Project. All rights reserved.";
@@ -0,0 +1,15 @@
/* Multiple Update message */
"%@ pending updates" = "%@ mises à jour en attente";
/* One Update message */
"1 pending update" = "1 mise à jour en attente";
/* Details label */
"Details" = "Détails";
/* Forced Install Date summary */
"One or more items must be installed by %@" = "Un article doit être installé avant le %@";
/* Software updates available message */
"Software updates available" = "Mises à jour logicielles disponibles";
@@ -0,0 +1,51 @@
/* Class = "NSMenuItem"; title = "munki-notifier"; ObjectID = "1Xt-HY-uBw"; */
"1Xt-HY-uBw.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Quit munki-notifier"; ObjectID = "4sb-4s-VLi"; */
"4sb-4s-VLi.title" = "Quit munki-notifier";
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */
"5QF-Oa-p0T.title" = "Edit";
/* Class = "NSMenuItem"; title = "About munki-notifier"; ObjectID = "5kV-Vb-QxS"; */
"5kV-Vb-QxS.title" = "About munki-notifier";
/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */
"AYu-sK-qS6.title" = "Main Menu";
/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */
"BOF-NM-1cW.title" = "Preferences…";
/* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */
"H8h-7b-M4v.title" = "View";
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */
"Kd2-mp-pUS.title" = "Show All";
/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */
"NMo-om-nkz.title" = "Services";
/* Class = "NSMenuItem"; title = "Hide munki-notifier"; ObjectID = "Olw-nP-bQN"; */
"Olw-nP-bQN.title" = "Hide munki-notifier";
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */
"Vdr-fp-XzO.title" = "Hide Others";
/* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */
"aUF-d1-5bR.title" = "Window";
/* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */
"dMs-cI-mzQ.title" = "File";
/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */
"hz9-B4-Xy5.title" = "Services";
/* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */
"jxT-CU-nIS.title" = "Format";
/* Class = "NSMenu"; title = "munki-notifier"; ObjectID = "uQy-DD-JDr"; */
"uQy-DD-JDr.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */
"wpr-3q-Mcd.title" = "Help";
@@ -0,0 +1,3 @@
/* (No Commment) */
"NSHumanReadableCopyright" = "Copyright © 2017 The Munki Project. All rights reserved.";
@@ -0,0 +1,15 @@
/* Multiple Update message */
"%@ pending updates" = "%@ aggiornamenti in sospeso";
/* One Update message */
"1 pending update" = "1 aggiornamento in sospeso";
/* Details label */
"Details" = "Dettagli";
/* Forced Install Date summary */
"One or more items must be installed by %@" = "Uno o più elementi devono essere installati da %@";
/* Software updates available message */
"Software updates available" = "Gli aggiornamenti software disponibili";
@@ -0,0 +1,51 @@
/* Class = "NSMenuItem"; title = "munki-notifier"; ObjectID = "1Xt-HY-uBw"; */
"1Xt-HY-uBw.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Quit munki-notifier"; ObjectID = "4sb-4s-VLi"; */
"4sb-4s-VLi.title" = "Quit munki-notifier";
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */
"5QF-Oa-p0T.title" = "Edit";
/* Class = "NSMenuItem"; title = "About munki-notifier"; ObjectID = "5kV-Vb-QxS"; */
"5kV-Vb-QxS.title" = "About munki-notifier";
/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */
"AYu-sK-qS6.title" = "Main Menu";
/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */
"BOF-NM-1cW.title" = "Preferences…";
/* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */
"H8h-7b-M4v.title" = "View";
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */
"Kd2-mp-pUS.title" = "Show All";
/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */
"NMo-om-nkz.title" = "Services";
/* Class = "NSMenuItem"; title = "Hide munki-notifier"; ObjectID = "Olw-nP-bQN"; */
"Olw-nP-bQN.title" = "Hide munki-notifier";
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */
"Vdr-fp-XzO.title" = "Hide Others";
/* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */
"aUF-d1-5bR.title" = "Window";
/* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */
"dMs-cI-mzQ.title" = "File";
/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */
"hz9-B4-Xy5.title" = "Services";
/* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */
"jxT-CU-nIS.title" = "Format";
/* Class = "NSMenu"; title = "munki-notifier"; ObjectID = "uQy-DD-JDr"; */
"uQy-DD-JDr.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */
"wpr-3q-Mcd.title" = "Help";
@@ -0,0 +1,3 @@
/* (No Commment) */
"NSHumanReadableCopyright" = "Copyright © 2017 The Munki Project. All rights reserved.";
@@ -0,0 +1,15 @@
/* Multiple Update message */
"%@ pending updates" = "%@個のアップデートを保留しています";
/* One Update message */
"1 pending update" = "1つのアップデートを保留しています";
/* Details label */
"Details" = "詳細";
/* Forced Install Date summary */
"One or more items must be installed by %@" = "%@までに、一つまたそれ以上のアイテムをインストールしなければいけません";
/* Software updates available message */
"Software updates available" = "利用可能なソフトウェアアップデート";
@@ -0,0 +1,51 @@
/* Class = "NSMenuItem"; title = "munki-notifier"; ObjectID = "1Xt-HY-uBw"; */
"1Xt-HY-uBw.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Quit munki-notifier"; ObjectID = "4sb-4s-VLi"; */
"4sb-4s-VLi.title" = "Quit munki-notifier";
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */
"5QF-Oa-p0T.title" = "Edit";
/* Class = "NSMenuItem"; title = "About munki-notifier"; ObjectID = "5kV-Vb-QxS"; */
"5kV-Vb-QxS.title" = "About munki-notifier";
/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */
"AYu-sK-qS6.title" = "Main Menu";
/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */
"BOF-NM-1cW.title" = "Preferences…";
/* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */
"H8h-7b-M4v.title" = "View";
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */
"Kd2-mp-pUS.title" = "Show All";
/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */
"NMo-om-nkz.title" = "Services";
/* Class = "NSMenuItem"; title = "Hide munki-notifier"; ObjectID = "Olw-nP-bQN"; */
"Olw-nP-bQN.title" = "Hide munki-notifier";
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */
"Vdr-fp-XzO.title" = "Hide Others";
/* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */
"aUF-d1-5bR.title" = "Window";
/* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */
"dMs-cI-mzQ.title" = "File";
/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */
"hz9-B4-Xy5.title" = "Services";
/* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */
"jxT-CU-nIS.title" = "Format";
/* Class = "NSMenu"; title = "munki-notifier"; ObjectID = "uQy-DD-JDr"; */
"uQy-DD-JDr.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */
"wpr-3q-Mcd.title" = "Help";
+9 -37
View File
@@ -1,41 +1,13 @@
//
// main.m
// munki-notifier
//
// Created by Greg Neagle on 2/23/17.
// Copyright © 2017 The Munki Project. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <Python.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *resourcePath = [mainBundle resourcePath];
NSArray *pythonPathArray = [NSArray arrayWithObjects: resourcePath, [resourcePath stringByAppendingPathComponent:@"PyObjC"], nil];
setenv("PYTHONPATH", [[pythonPathArray componentsJoinedByString:@":"] UTF8String], 1);
NSArray *possibleMainExtensions = [NSArray arrayWithObjects: @"py", @"pyc", @"pyo", nil];
NSString *mainFilePath = nil;
for (NSString *possibleMainExtension in possibleMainExtensions) {
mainFilePath = [mainBundle pathForResource: @"main" ofType: possibleMainExtension];
if ( mainFilePath != nil ) break;
}
if ( !mainFilePath ) {
[NSException raise: NSInternalInconsistencyException format: @"%s:%d main() Failed to find the Main.{py,pyc,pyo} file in the application wrapper's Resources directory.", __FILE__, __LINE__];
}
Py_SetProgramName("/usr/bin/python");
Py_Initialize();
PySys_SetArgv(argc, (char **)argv);
const char *mainFilePathPtr = [mainFilePath UTF8String];
FILE *mainFile = fopen(mainFilePathPtr, "r");
int result = PyRun_SimpleFile(mainFile, (char *)[[mainFilePath lastPathComponent] UTF8String]);
if ( result != 0 ) {
[NSException raise: NSInternalInconsistencyException
format: @"%s:%d main() PyRun_SimpleFile failed with file '%@'. See console for errors.", __FILE__, __LINE__, mainFilePath];
}
return result;
}
return NSApplicationMain(argc, argv);
}
@@ -1,21 +0,0 @@
# -*- coding: utf-8 -*-
#
# main.py
# munki-notifier
#
# Created by Greg Neagle on 4/11/15.
# Copyright (c) 2015 The Munki Project. All rights reserved.
#
# import modules required by application
import objc
import Foundation
import AppKit
from PyObjCTools import AppHelper
# import modules containing classes required to start application and load MainMenu.nib
import AppDelegate
# pass control to AppKit
AppHelper.runEventLoop()
@@ -0,0 +1,3 @@
/* (No Commment) */
"NSHumanReadableCopyright" = "Copyright © 2017 The Munki Project. All rights reserved.";
@@ -0,0 +1,15 @@
/* Multiple Update message */
"%@ pending updates" = "%@ ventende oppdateringer";
/* One Update message */
"1 pending update" = "1 ventende oppdatering";
/* Details label */
"Details" = "Detaljer";
/* Forced Install Date summary */
"One or more items must be installed by %@" = "Et eller flere objekter må installeres senest %@";
/* Software updates available message */
"Software updates available" = "Programvareoppdateringer tilgjengelige";
@@ -0,0 +1,51 @@
/* Class = "NSMenuItem"; title = "munki-notifier"; ObjectID = "1Xt-HY-uBw"; */
"1Xt-HY-uBw.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Quit munki-notifier"; ObjectID = "4sb-4s-VLi"; */
"4sb-4s-VLi.title" = "Quit munki-notifier";
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */
"5QF-Oa-p0T.title" = "Edit";
/* Class = "NSMenuItem"; title = "About munki-notifier"; ObjectID = "5kV-Vb-QxS"; */
"5kV-Vb-QxS.title" = "About munki-notifier";
/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */
"AYu-sK-qS6.title" = "Main Menu";
/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */
"BOF-NM-1cW.title" = "Preferences…";
/* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */
"H8h-7b-M4v.title" = "View";
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */
"Kd2-mp-pUS.title" = "Show All";
/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */
"NMo-om-nkz.title" = "Services";
/* Class = "NSMenuItem"; title = "Hide munki-notifier"; ObjectID = "Olw-nP-bQN"; */
"Olw-nP-bQN.title" = "Hide munki-notifier";
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */
"Vdr-fp-XzO.title" = "Hide Others";
/* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */
"aUF-d1-5bR.title" = "Window";
/* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */
"dMs-cI-mzQ.title" = "File";
/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */
"hz9-B4-Xy5.title" = "Services";
/* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */
"jxT-CU-nIS.title" = "Format";
/* Class = "NSMenu"; title = "munki-notifier"; ObjectID = "uQy-DD-JDr"; */
"uQy-DD-JDr.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */
"wpr-3q-Mcd.title" = "Help";
@@ -0,0 +1,3 @@
/* (No Commment) */
"NSHumanReadableCopyright" = "Copyright © 2017 The Munki Project. All rights reserved.";
@@ -0,0 +1,15 @@
/* Multiple Update message */
"%@ pending updates" = "%@ wachtende updates";
/* One Update message */
"1 pending update" = "1 wachtende update";
/* Details label */
"Details" = "Details";
/* Forced Install Date summary */
"One or more items must be installed by %@" = "Eén of meer items moeten voor %@ worden geïnstalleerd";
/* Software updates available message */
"Software updates available" = "Software-updates beschikbaar";
@@ -0,0 +1,51 @@
/* Class = "NSMenuItem"; title = "munki-notifier"; ObjectID = "1Xt-HY-uBw"; */
"1Xt-HY-uBw.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Quit munki-notifier"; ObjectID = "4sb-4s-VLi"; */
"4sb-4s-VLi.title" = "Quit munki-notifier";
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */
"5QF-Oa-p0T.title" = "Edit";
/* Class = "NSMenuItem"; title = "About munki-notifier"; ObjectID = "5kV-Vb-QxS"; */
"5kV-Vb-QxS.title" = "About munki-notifier";
/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */
"AYu-sK-qS6.title" = "Main Menu";
/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */
"BOF-NM-1cW.title" = "Preferences…";
/* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */
"H8h-7b-M4v.title" = "View";
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */
"Kd2-mp-pUS.title" = "Show All";
/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */
"NMo-om-nkz.title" = "Services";
/* Class = "NSMenuItem"; title = "Hide munki-notifier"; ObjectID = "Olw-nP-bQN"; */
"Olw-nP-bQN.title" = "Hide munki-notifier";
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */
"Vdr-fp-XzO.title" = "Hide Others";
/* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */
"aUF-d1-5bR.title" = "Window";
/* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */
"dMs-cI-mzQ.title" = "File";
/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */
"hz9-B4-Xy5.title" = "Services";
/* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */
"jxT-CU-nIS.title" = "Format";
/* Class = "NSMenu"; title = "munki-notifier"; ObjectID = "uQy-DD-JDr"; */
"uQy-DD-JDr.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */
"wpr-3q-Mcd.title" = "Help";
@@ -0,0 +1,3 @@
/* (No Commment) */
"NSHumanReadableCopyright" = "Copyright © 2017 The Munki Project. All rights reserved.";
@@ -0,0 +1,15 @@
/* Multiple Update message */
"%@ pending updates" = "%@ отложенных обновлений";
/* One Update message */
"1 pending update" = "1 отложенное обновление";
/* Details label */
"Details" = "Подробнее";
/* Forced Install Date summary */
"One or more items must be installed by %@" = "Один или несколько элементов должны быть установлены до %@";
/* Software updates available message */
"Software updates available" = "Обновления программного обеспечения, доступные";
@@ -0,0 +1,51 @@
/* Class = "NSMenuItem"; title = "munki-notifier"; ObjectID = "1Xt-HY-uBw"; */
"1Xt-HY-uBw.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Quit munki-notifier"; ObjectID = "4sb-4s-VLi"; */
"4sb-4s-VLi.title" = "Quit munki-notifier";
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */
"5QF-Oa-p0T.title" = "Edit";
/* Class = "NSMenuItem"; title = "About munki-notifier"; ObjectID = "5kV-Vb-QxS"; */
"5kV-Vb-QxS.title" = "About munki-notifier";
/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */
"AYu-sK-qS6.title" = "Main Menu";
/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */
"BOF-NM-1cW.title" = "Preferences…";
/* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */
"H8h-7b-M4v.title" = "View";
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */
"Kd2-mp-pUS.title" = "Show All";
/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */
"NMo-om-nkz.title" = "Services";
/* Class = "NSMenuItem"; title = "Hide munki-notifier"; ObjectID = "Olw-nP-bQN"; */
"Olw-nP-bQN.title" = "Hide munki-notifier";
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */
"Vdr-fp-XzO.title" = "Hide Others";
/* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */
"aUF-d1-5bR.title" = "Window";
/* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */
"dMs-cI-mzQ.title" = "File";
/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */
"hz9-B4-Xy5.title" = "Services";
/* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */
"jxT-CU-nIS.title" = "Format";
/* Class = "NSMenu"; title = "munki-notifier"; ObjectID = "uQy-DD-JDr"; */
"uQy-DD-JDr.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */
"wpr-3q-Mcd.title" = "Help";
@@ -0,0 +1,3 @@
/* (No Commment) */
"NSHumanReadableCopyright" = "Copyright © 2017 The Munki Project. All rights reserved.";
@@ -0,0 +1,15 @@
/* Multiple Update message */
"%@ pending updates" = "%@ uppdateringar väntar";
/* One Update message */
"1 pending update" = "1 uppdatering väntar";
/* Details label */
"Details" = "Detaljer";
/* Forced Install Date summary */
"One or more items must be installed by %@" = "Ett eller flera objekt måste installeras senast %@";
/* Software updates available message */
"Software updates available" = "Programuppdateringar finns";
@@ -0,0 +1,51 @@
/* Class = "NSMenuItem"; title = "munki-notifier"; ObjectID = "1Xt-HY-uBw"; */
"1Xt-HY-uBw.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Quit munki-notifier"; ObjectID = "4sb-4s-VLi"; */
"4sb-4s-VLi.title" = "Quit munki-notifier";
/* Class = "NSMenuItem"; title = "Edit"; ObjectID = "5QF-Oa-p0T"; */
"5QF-Oa-p0T.title" = "Edit";
/* Class = "NSMenuItem"; title = "About munki-notifier"; ObjectID = "5kV-Vb-QxS"; */
"5kV-Vb-QxS.title" = "About munki-notifier";
/* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */
"AYu-sK-qS6.title" = "Main Menu";
/* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */
"BOF-NM-1cW.title" = "Preferences…";
/* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */
"H8h-7b-M4v.title" = "View";
/* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */
"Kd2-mp-pUS.title" = "Show All";
/* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */
"NMo-om-nkz.title" = "Services";
/* Class = "NSMenuItem"; title = "Hide munki-notifier"; ObjectID = "Olw-nP-bQN"; */
"Olw-nP-bQN.title" = "Hide munki-notifier";
/* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */
"Vdr-fp-XzO.title" = "Hide Others";
/* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */
"aUF-d1-5bR.title" = "Window";
/* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */
"dMs-cI-mzQ.title" = "File";
/* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */
"hz9-B4-Xy5.title" = "Services";
/* Class = "NSMenuItem"; title = "Format"; ObjectID = "jxT-CU-nIS"; */
"jxT-CU-nIS.title" = "Format";
/* Class = "NSMenu"; title = "munki-notifier"; ObjectID = "uQy-DD-JDr"; */
"uQy-DD-JDr.title" = "munki-notifier";
/* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */
"wpr-3q-Mcd.title" = "Help";