diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac9bff6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.pyc +*.pyo +.DS_Store \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f34cbe8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,23 @@ +All the works are available under the MIT license. **Except** for +‘Terminal.icns’, which is a copy of Apple’s Terminal.app icon and as such is +copyright of Apple. + +Copyright (C) 2012 Vlad Syabruk + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..9fb9ddd --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,3 @@ +graft pync/vendor +include README.md LICENSE +global-exclude .DS_Store \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..372a908 --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +pync +==== + +A simple Python wrapper around the [`terminal-notifier`][HOMEPAGE] command-line +tool, which allows you to send User Notifications to the Notification Center on +Mac OS X 10.8, or higher. + + +Installation +------------ + +``` +$ python setup.py install +``` + +Usage +----- + +For full information on all the options, see the tool’s [README][README]. + +Examples are: + +```python +from pync import Notifier + +Notifier.notify('Hello World') +Notifier.notify('Hello World', title='Python') +Notifier.notify('Hello World', group=os.getpid()) +Notifier.notify('Hello World', activate='com.apple.Safari') +Notifier.notify('Hello World', open='http://github.com/') +Notifier.notify('Hello World', execute='say "OMG"') + +Notifier.remove(os.getpid()) + +Notifier.list(os.getpid()) +``` + + +License +------- + +All the works are available under the MIT license. **Except** for +‘Terminal.icns’, which is a copy of Apple’s Terminal.app icon and as such is +copyright of Apple. + +See [LICENSE][LICENSE] for details. + +[HOMEPAGE]: https://github.com/alloy/terminal-notifier +[README]: https://github.com/alloy/terminal-notifier/blob/master/README.markdown +[LICENSE]: https://github.com/setem/pync/blob/master/LICENSE \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pync/TerminalNotifier.py b/pync/TerminalNotifier.py new file mode 100644 index 0000000..cbb78d7 --- /dev/null +++ b/pync/TerminalNotifier.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import platform +import subprocess +import itertools +import time +from datetime import datetime +from dateutil.parser import parse + +LIST_FIELDS = ["group", "title", "sublitle", "message", "delivered_at"] + +class TerminalNotifier(object): + def __init__(self): + """ + Raises if not supported on the current platform or if terminal-notifier.app does not find. + """ + self.bin_path = os.path.join(os.path.dirname(__file__), "vendor/terminal-notifier.app/Contents/MacOS/terminal-notifier") + if not os.access(self.bin_path, os.X_OK): + os.chmod(self.bin_path, 111) + if not self.is_available: + raise Exception("pync is only supported on Mac OS X 10.8, or higher.") + if not os.path.exists(self.bin_path): + raise Exception("terminal-notifier.app does not exist.") + + def notify(self, message, **kwargs): + """ + Sends a User Notification. + + The available options are `title`, `group`, `activate`, `open`, and + `execute`. For a description of each option see: + + https://github.com/alloy/terminal-notifier/blob/master/README.markdown + + Examples are: + + Notifier = TerminalNotifier() + + Notifier.notify('Hello World') + Notifier.notify('Hello World', title='Python') + Notifier.notify('Hello World', group=os.getpid()) + Notifier.notify('Hello World', activate='com.apple.Safari') + Notifier.notify('Hello World', open='http://github.com/') + Notifier.notify('Hello World', execute='say "OMG"') + + """ + args = ['-message', message] + args += itertools.chain.from_iterable([("-%s" % arg, str(key)) for arg, key in kwargs.items()]) + self.execute(args) + + def execute(self, verbose): + output = subprocess.Popen([self.bin_path,] + verbose, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + if output.returncode: + raise Exception("Some error during subprocess call.") + return output + + def remove(self, group="ALL"): + """ + Removes a notification that was previously sent with the specified + ‘group’ ID, if one exists. + + If no ‘group’ ID is given, all notifications are removed. + """ + self.execute(["-remove", group]) + + def list(self, group="ALL"): + """ + If a ‘group’ ID is given, and a notification for that group exists, + returns a dict with details about the notification. + + If no ‘group’ ID is given, an array of hashes describing all + notifications. + + If no information is available this will return []. + """ + output = self.execute(["-list", group]).communicate()[0] + res = list() + for line in output.splitlines()[1:-1]: + res.append(dict(zip(LIST_FIELDS, line.split("\t")))) + try: + res[-1]["delivered_at"] = parse(res[-1]["delivered_at"]) + except ValueError: + pass + + return res + + @staticmethod + def is_available(self): + """ Returns wether or not the current platform is Mac OS X 10.8, or higher.""" + return platform.system() == "Darwin" and platform.mac_ver()[0] >= '10.8' + +Notifier = TerminalNotifier() + +if __name__ == '__main__': + Notifier.notify("Notification from %s" % __file__, open="http://github.com") + diff --git a/pync/__init__.py b/pync/__init__.py new file mode 100644 index 0000000..a709f16 --- /dev/null +++ b/pync/__init__.py @@ -0,0 +1,3 @@ +__version__ = "1.0" + +from TerminalNotifier import Notifier diff --git a/pync/vendor/terminal-notifier.app/Contents/Info.plist b/pync/vendor/terminal-notifier.app/Contents/Info.plist new file mode 100644 index 0000000..044e221 --- /dev/null +++ b/pync/vendor/terminal-notifier.app/Contents/Info.plist @@ -0,0 +1,52 @@ + + + + + BuildMachineOSBuild + 12A269 + CFBundleDevelopmentRegion + en + CFBundleExecutable + terminal-notifier + CFBundleIconFile + Terminal + CFBundleIdentifier + nl.superalloy.oss.terminal-notifier + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + terminal-notifier + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.4.2 + CFBundleSignature + ???? + CFBundleVersion + 7 + DTCompiler + + DTPlatformBuild + 4F243 + DTPlatformVersion + GM + DTSDKBuild + 12A264 + DTSDKName + macosx10.8 + DTXcode + 0440 + DTXcodeBuild + 4F243 + LSMinimumSystemVersion + 10.8 + LSUIElement + + NSHumanReadableCopyright + Copyright © 2012 Eloy Durán. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/pync/vendor/terminal-notifier.app/Contents/MacOS/terminal-notifier b/pync/vendor/terminal-notifier.app/Contents/MacOS/terminal-notifier new file mode 100755 index 0000000..3303fe7 Binary files /dev/null and b/pync/vendor/terminal-notifier.app/Contents/MacOS/terminal-notifier differ diff --git a/pync/vendor/terminal-notifier.app/Contents/PkgInfo b/pync/vendor/terminal-notifier.app/Contents/PkgInfo new file mode 100644 index 0000000..bd04210 --- /dev/null +++ b/pync/vendor/terminal-notifier.app/Contents/PkgInfo @@ -0,0 +1 @@ +APPL???? \ No newline at end of file diff --git a/pync/vendor/terminal-notifier.app/Contents/Resources/Terminal.icns b/pync/vendor/terminal-notifier.app/Contents/Resources/Terminal.icns new file mode 100644 index 0000000..8d8f5c2 Binary files /dev/null and b/pync/vendor/terminal-notifier.app/Contents/Resources/Terminal.icns differ diff --git a/pync/vendor/terminal-notifier.app/Contents/Resources/en.lproj/Credits.rtf b/pync/vendor/terminal-notifier.app/Contents/Resources/en.lproj/Credits.rtf new file mode 100644 index 0000000..46576ef --- /dev/null +++ b/pync/vendor/terminal-notifier.app/Contents/Resources/en.lproj/Credits.rtf @@ -0,0 +1,29 @@ +{\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\ +} diff --git a/pync/vendor/terminal-notifier.app/Contents/Resources/en.lproj/InfoPlist.strings b/pync/vendor/terminal-notifier.app/Contents/Resources/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..5e45963 Binary files /dev/null and b/pync/vendor/terminal-notifier.app/Contents/Resources/en.lproj/InfoPlist.strings differ diff --git a/pync/vendor/terminal-notifier.app/Contents/Resources/en.lproj/MainMenu.nib b/pync/vendor/terminal-notifier.app/Contents/Resources/en.lproj/MainMenu.nib new file mode 100644 index 0000000..f8301c7 Binary files /dev/null and b/pync/vendor/terminal-notifier.app/Contents/Resources/en.lproj/MainMenu.nib differ diff --git a/pync/vendor/terminal-notifier.app/Contents/_CodeSignature/CodeResources b/pync/vendor/terminal-notifier.app/Contents/_CodeSignature/CodeResources new file mode 100644 index 0000000..10922df --- /dev/null +++ b/pync/vendor/terminal-notifier.app/Contents/_CodeSignature/CodeResources @@ -0,0 +1,61 @@ + + + + + files + + Resources/Terminal.icns + + Oq9GtJM1DqcGF1JCHiEgb0hoN6I= + + Resources/en.lproj/Credits.rtf + + hash + + YKJIFIsxneJuNkJNJQIcJIjiPOg= + + optional + + + Resources/en.lproj/InfoPlist.strings + + hash + + MiLKDDnrUKr4EmuvhS5VQwxHGK8= + + optional + + + Resources/en.lproj/MainMenu.nib + + hash + + N1QqAM17vgDk7XNtv27koaE4IhE= + + optional + + + + rules + + ^Resources/ + + ^Resources/.*\.lproj/ + + optional + + weight + 1000 + + ^Resources/.*\.lproj/locversion.plist$ + + omit + + weight + 1100 + + ^version.plist$ + + + + diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..0b5e528 --- /dev/null +++ b/setup.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +from setuptools import setup, find_packages + +file_contents = [] +for file_name in ('README.md',): + path = os.path.join(os.path.dirname(__file__), file_name) + file_contents.append(open(path).read()) +long_description = '\n\n'.join(file_contents) + +setup(name = 'pync', + version = '1.0', + description = 'Python Wrapper for Mac OS 10.8 Notification Center', + long_description = long_description, + author = 'Vladislav Syabruk', + author_email = 'sjabrik@gmail.com', + url = 'https://github.com/setem/pync', + download_url = 'https://github.com/downloads/setem/pync/pync_1.0.zip', + license = "MIT", + platforms = "MacOS X", + keywords = "mac notification center wrapper", + zip_safe = True, + include_package_data = True, + install_requires = [ + 'python-dateutil>=2.0' + ], + packages = find_packages(), +)