├── pync ├── vendor │ └── terminal-notifier-2.0.0 │ │ ├── terminal-notifier.app │ │ └── Contents │ │ │ ├── PkgInfo │ │ │ ├── MacOS │ │ │ └── terminal-notifier │ │ │ ├── Resources │ │ │ ├── Terminal.icns │ │ │ └── en.lproj │ │ │ │ ├── MainMenu.nib │ │ │ │ ├── InfoPlist.strings │ │ │ │ └── Credits.rtf │ │ │ └── Info.plist │ │ └── README.markdown ├── __init__.py └── TerminalNotifier.py ├── MANIFEST.in ├── .travis.yml ├── .gitignore ├── .github └── ISSUE_TEMPLATE │ ├── Feature_request.md │ └── Bug_report.md ├── LICENSE ├── setup.py └── README.md /pync/vendor/terminal-notifier-2.0.0/terminal-notifier.app/Contents/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | global-exclude .DS_Store 2 | recursive-include pync/vendor * 3 | include README.md 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | install: 5 | - "python setup.py -q install" -------------------------------------------------------------------------------- /pync/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "2.0.3" 2 | 3 | from .TerminalNotifier import Notifier, notify, remove_notifications, list_notifications 4 | -------------------------------------------------------------------------------- /pync/vendor/terminal-notifier-2.0.0/terminal-notifier.app/Contents/MacOS/terminal-notifier: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syabruk/pync/HEAD/pync/vendor/terminal-notifier-2.0.0/terminal-notifier.app/Contents/MacOS/terminal-notifier -------------------------------------------------------------------------------- /pync/vendor/terminal-notifier-2.0.0/terminal-notifier.app/Contents/Resources/Terminal.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syabruk/pync/HEAD/pync/vendor/terminal-notifier-2.0.0/terminal-notifier.app/Contents/Resources/Terminal.icns -------------------------------------------------------------------------------- /pync/vendor/terminal-notifier-2.0.0/terminal-notifier.app/Contents/Resources/en.lproj/MainMenu.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syabruk/pync/HEAD/pync/vendor/terminal-notifier-2.0.0/terminal-notifier.app/Contents/Resources/en.lproj/MainMenu.nib -------------------------------------------------------------------------------- /pync/vendor/terminal-notifier-2.0.0/terminal-notifier.app/Contents/Resources/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syabruk/pync/HEAD/pync/vendor/terminal-notifier-2.0.0/terminal-notifier.app/Contents/Resources/en.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[co] 2 | 3 | # Packages 4 | *.egg 5 | *.egg-info 6 | dist 7 | build 8 | eggs 9 | parts 10 | bin 11 | var 12 | sdist 13 | develop-eggs 14 | .installed.cfg 15 | 16 | # Installer logs 17 | pip-log.txt 18 | 19 | # Unit test / coverage reports 20 | .coverage 21 | .tox 22 | 23 | #Translations 24 | *.mo 25 | 26 | #Mr Developer 27 | .mr.developer.cfg -------------------------------------------------------------------------------- /pync/vendor/terminal-notifier-2.0.0/terminal-notifier.app/Contents/Resources/en.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} 2 | {\colortbl;\red255\green255\blue255;} 3 | \paperw9840\paperh8400 4 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 5 | 6 | \f0\b\fs24 \cf0 Engineering: 7 | \b0 \ 8 | Some people\ 9 | \ 10 | 11 | \b Human Interface Design: 12 | \b0 \ 13 | Some other people\ 14 | \ 15 | 16 | \b Testing: 17 | \b0 \ 18 | Hopefully not nobody\ 19 | \ 20 | 21 | \b Documentation: 22 | \b0 \ 23 | Whoever\ 24 | \ 25 | 26 | \b With special thanks to: 27 | \b0 \ 28 | Mom\ 29 | } 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Desktop (please complete the following information):** 24 | - OS: [e.g. MacOS] 25 | - Version [e.g. 10.10] 26 | 27 | **Additional context** 28 | Add any other context about the problem here. 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | All the works are available under the MIT license. **Except** for 2 | ‘Terminal.icns’, which is a copy of Apple’s Terminal.app icon and as such is 3 | copyright of Apple. 4 | 5 | Copyright (C) 2012 Vlad Syabruk 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import codecs 6 | from setuptools import setup, find_packages 7 | 8 | 9 | here = os.path.abspath(os.path.dirname(__file__)) 10 | 11 | readme_file = os.path.join(here, 'README.md') 12 | try: 13 | from m2r import parse_from_file 14 | long_description = parse_from_file(readme_file) 15 | except ImportError: 16 | with codecs.open(readme_file, encoding='utf-8') as f: 17 | long_description = f.read() 18 | 19 | terminal_notifier_files = [] 20 | for root, dirs, files in os.walk('pync/vendor/'): 21 | root = '/'.join(root.split('/')[1:]) 22 | for f in files: 23 | terminal_notifier_files.append(os.path.join(root, f)) 24 | 25 | setup(name = 'pync', 26 | version = "2.0.4", 27 | description = 'Python Wrapper for Mac OS 10.10 Notification Center', 28 | long_description = long_description, 29 | author = 'Vladislav Syabruk', 30 | author_email = 'sjabrik@gmail.com', 31 | url = 'https://github.com/setem/pync', 32 | license = "MIT", 33 | platforms = "MacOS X", 34 | keywords = "mac notification center wrapper", 35 | zip_safe = True, 36 | include_package_data = True, 37 | install_requires = [ 38 | 'python-dateutil>=2.0' 39 | ], 40 | packages = find_packages(), 41 | classifiers = [ 42 | 'Development Status :: 5 - Production/Stable', 43 | 'Environment :: Console', 44 | 'License :: OSI Approved :: MIT License', 45 | 'Programming Language :: Python :: 2.7', 46 | 'Programming Language :: Python :: 3.4', 47 | 'Programming Language :: Python :: 3.5', 48 | 'Programming Language :: Python :: 3.6', 49 | 'Environment :: MacOS X', 50 | 'Topic :: Terminals', 51 | 'Topic :: Utilities', 52 | 'Topic :: Software Development :: Libraries :: Python Modules' 53 | ] 54 | ) 55 | -------------------------------------------------------------------------------- /pync/vendor/terminal-notifier-2.0.0/terminal-notifier.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 17A405 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | terminal-notifier 11 | CFBundleIconFile 12 | Terminal 13 | CFBundleIdentifier 14 | fr.julienxx.oss.terminal-notifier 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | terminal-notifier 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 2.0.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleSupportedPlatforms 26 | 27 | MacOSX 28 | 29 | CFBundleVersion 30 | 15 31 | DTCompiler 32 | com.apple.compilers.llvm.clang.1_0 33 | DTPlatformBuild 34 | 9A1004 35 | DTPlatformVersion 36 | GM 37 | DTSDKBuild 38 | 17A360 39 | DTSDKName 40 | macosx10.13 41 | DTXcode 42 | 0901 43 | DTXcodeBuild 44 | 9A1004 45 | LSMinimumSystemVersion 46 | 10.10 47 | LSUIElement 48 | 49 | NSAppTransportSecurity 50 | 51 | NSAllowsArbitraryLoads 52 | 53 | 54 | NSHumanReadableCopyright 55 | Copyright © 2012-2017 Eloy Durán, Julien Blanchard. All rights reserved. 56 | NSMainNibFile 57 | MainMenu 58 | NSPrincipalClass 59 | NSApplication 60 | NSUserNotificationAlertStyle 61 | banner 62 | 63 | 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pync 2 | [![PyPI - License](https://img.shields.io/pypi/l/pync.svg)](https://github.com/SeTeM/pync/blob/master/LICENSE) 3 | [![PyPI](https://img.shields.io/pypi/v/pync.svg)](https://pypi.org/project/pync/) 4 | ![GitHub issues](https://img.shields.io/github/issues-raw/SeTeM/pync.svg) 5 | ![GitHub pull requests](https://img.shields.io/github/issues-pr/SeTeM/pync.svg) 6 | [![GitHub forks](https://img.shields.io/github/forks/SeTeM/pync.svg?style=social&label=Fork)](https://github.com/SeTeM/pync) 7 | [![GitHub stars](https://img.shields.io/github/stars/SeTeM/pync.svg?style=social&label=Stars)](https://github.com/SeTeM/pync) 8 | 9 | A simple Python wrapper around the [terminal-notifier][HOMEPAGE] command-line tool (version 2.0.0), which allows you to send User Notifications to the Notification Center on Mac OS X 10.10, or higher. 10 | 11 | ![Screenshot](http://f.cl.ly/items/1k051n3k0u0i101m1i0U/Screen%20Shot%202012-08-24%20at%2012.20.40%20PM.png) 12 | 13 | ### Installation 14 | 15 | ```bash 16 | pip install pync 17 | ``` 18 | or 19 | ```bash 20 | pip install git+https://github.com/SeTeM/pync.git 21 | ``` 22 | or 23 | ```bash 24 | git clone git://github.com/SeTeM/pync.git 25 | cd pync 26 | python setup.py install 27 | ``` 28 | 29 | ### Usage 30 | 31 | For full information on all the options, see the tool’s [README][README]. 32 | 33 | #### Examples: 34 | 35 | Using the notify function 36 | ```python 37 | import pync 38 | 39 | pync.notify('Hello World') 40 | pync.notify('Hello World', title='Python') 41 | pync.notify('Hello World', group=os.getpid()) 42 | pync.notify('Hello World', activate='com.apple.Safari') 43 | pync.notify('Hello World', open='http://github.com/') 44 | pync.notify('Hello World', execute='say "OMG"') 45 | pync.notify('Hello World', appIcon='https://assets-cdn.github.com/images/modules/logos_page/Octocat.png') 46 | 47 | pync.remove_notifications(os.getpid()) 48 | 49 | pync.list_notifications(os.getpid()) 50 | ``` 51 | 52 | Using the notifier object 53 | ```python 54 | from pync import Notifier 55 | 56 | Notifier.notify('Hello World') 57 | Notifier.notify('Hello World', title='Python') 58 | Notifier.notify('Hello World', group=os.getpid()) 59 | Notifier.notify('Hello World', activate='com.apple.Safari') 60 | Notifier.notify('Hello World', open='http://github.com/') 61 | Notifier.notify('Hello World', execute='say "OMG"') 62 | Notifier.notify('Hello World', appIcon='https://assets-cdn.github.com/images/modules/logos_page/Octocat.png') 63 | 64 | Notifier.remove(os.getpid()) 65 | 66 | Notifier.list(os.getpid()) 67 | ``` 68 | 69 | 70 | ### License 71 | 72 | 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. 73 | 74 | See [LICENSE][LICENSE] for details. 75 | 76 | [HOMEPAGE]: https://github.com/alloy/terminal-notifier 77 | [README]: https://github.com/alloy/terminal-notifier/blob/master/README.markdown 78 | [LICENSE]: https://github.com/setem/pync/blob/master/LICENSE 79 | -------------------------------------------------------------------------------- /pync/TerminalNotifier.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import platform 6 | import subprocess 7 | import sys 8 | 9 | from dateutil.parser import parse 10 | 11 | LIST_FIELDS = ["group", "title", "subtitle", "message", "delivered_at", "appIcon"] 12 | 13 | 14 | class TerminalNotifier(object): 15 | TERMINAL_NOTIFIER_VERSION = "2.0.0" 16 | 17 | def __init__(self, wait=False): 18 | """ 19 | Raises an exception if not supported on the current platform or 20 | if terminal-notifier was not found. 21 | """ 22 | self._wait = wait 23 | proc = subprocess.Popen(["which", "terminal-notifier"], stdout=subprocess.PIPE) 24 | env_bin_path = proc.communicate()[0].strip() 25 | if env_bin_path and os.path.exists(env_bin_path): 26 | self.bin_path = os.path.realpath(env_bin_path) 27 | elif os.path.exists("/usr/local/bin/terminal-notifier"): 28 | self.bin_path = os.path.join("/usr/local/bin/", "terminal-notifier") 29 | else: 30 | self.app_path = os.path.join( 31 | os.path.dirname(__file__), 32 | "vendor/terminal-notifier-%s/terminal-notifier.app" % self.TERMINAL_NOTIFIER_VERSION 33 | ) 34 | self.bin_path = os.path.join(self.app_path, "Contents/MacOS/terminal-notifier") 35 | 36 | if not self.is_available(): 37 | raise Exception("pync is only supported on Mac OS X 10.8, or higher.") 38 | 39 | if not os.path.exists(self.bin_path): 40 | raise Exception("pync was not properly installed. Head over to https://github.com/SeTeM/pync/" 41 | " and file a bug.") 42 | 43 | if not os.access(self.bin_path, os.X_OK): 44 | os.chmod(self.bin_path, 111) 45 | if not os.access(self.bin_path, os.X_OK): 46 | raise Exception("You have no privileges to execute \"%s\"" % self.bin_path) 47 | 48 | def notify(self, message, **kwargs): 49 | """ 50 | Sends a User Notification. 51 | 52 | The available options are `title`, `group`, `activate`, `open`, `sound`, and 53 | `execute`. For a description of each option see: 54 | 55 | https://github.com/alloy/terminal-notifier/blob/master/README.markdown 56 | 57 | Examples are: 58 | 59 | Notifier = TerminalNotifier() 60 | 61 | Notifier.notify('Hello World') 62 | Notifier.notify('Hello World', title='Python') 63 | Notifier.notify('Hello World', sound='Ping') 64 | Notifier.notify('Hello World', group=os.getpid()) 65 | Notifier.notify('Hello World', activate='com.apple.Safari') 66 | Notifier.notify('Hello World', open='http://github.com/') 67 | Notifier.notify('Hello World', execute='say "OMG"') 68 | 69 | The options `wait` is a boolean for whether or not we need to wait (block) for the background process to finish 70 | """ 71 | 72 | if sys.version_info < (3,): 73 | message = message.encode('utf-8', 'replace') 74 | 75 | self._wait = kwargs.pop('wait', False) 76 | 77 | args = ['-message', message] 78 | args += [a for b in [("-%s" % arg, str(key)) for arg, key in kwargs.items()] for a in b] # flatten list 79 | 80 | return self.execute(args) 81 | 82 | def execute(self, args): 83 | args = [str(arg) for arg in args] 84 | output = subprocess.Popen([self.bin_path, ] + args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 85 | 86 | if self._wait: 87 | output.wait() 88 | 89 | if output.returncode: 90 | raise Exception("Some error during subprocess call.") 91 | 92 | return output 93 | 94 | def remove(self, group="ALL"): 95 | """ 96 | Removes a notification that was previously sent with the specified 97 | ‘group’ ID, if one exists. 98 | 99 | If no ‘group’ ID is given, all notifications are removed. 100 | """ 101 | return self.execute(["-remove", group]) 102 | 103 | def list(self, group="ALL"): 104 | """ 105 | If a ‘group’ ID is given, and a notification for that group exists, 106 | returns a dict with details about the notification. 107 | 108 | If no ‘group’ ID is given, an array of hashes describing all 109 | notifications. 110 | 111 | If no information is available this will return []. 112 | """ 113 | 114 | output = self.execute(["-list", group]).communicate()[0] 115 | res = list() 116 | 117 | for line in output.splitlines()[1:]: 118 | res.append(dict(zip(LIST_FIELDS, line.decode().split("\t")))) 119 | try: 120 | res[-1]["delivered_at"] = parse(res[-1]["delivered_at"]) 121 | except ValueError: 122 | pass 123 | 124 | return res 125 | 126 | @staticmethod 127 | def is_available(): 128 | """ Returns whether or not the current platform is Mac OS X 10.8, or higher.""" 129 | if not platform.system() == 'Darwin': 130 | return False 131 | 132 | major, minor = platform.mac_ver()[0].split('.')[:2] 133 | 134 | return int(major) > 10 or int(minor) >= 8 135 | 136 | 137 | Notifier = TerminalNotifier() 138 | 139 | 140 | def notify(message, **kwargs): 141 | """ 142 | Sends a User Notification. 143 | 144 | The available options are `title`, `group`, `activate`, `open`, `sound`, and 145 | `execute`. For a description of each option see: 146 | 147 | https://github.com/alloy/terminal-notifier/blob/master/README.markdown 148 | 149 | Examples are: 150 | 151 | import pync 152 | 153 | pync.notify('Hello World') 154 | pync.notify('Hello World', title='Python') 155 | pync.notify('Hello World', sound='Ping') 156 | pync.notify('Hello World', group=os.getpid()) 157 | pync.notify('Hello World', activate='com.apple.Safari') 158 | pync.notify('Hello World', open='http://github.com/') 159 | pync.notify('Hello World', execute='say "OMG"') 160 | 161 | The options `wait` is a boolean for whether or not we need to wait (block) for the background process to finish 162 | """ 163 | Notifier.notify(message, **kwargs) 164 | 165 | 166 | def remove_notifications(group="ALL"): 167 | """ 168 | Removes a notification that was previously sent with the specified 169 | ‘group’ ID, if one exists. 170 | 171 | If no ‘group’ ID is given, all notifications are removed. 172 | """ 173 | return Notifier.execute(["-remove", group]) 174 | 175 | 176 | def list_notifications(self, group="ALL"): 177 | """ 178 | If a ‘group’ ID is given, and a notification for that group exists, 179 | returns a dict with details about the notification. 180 | 181 | If no ‘group’ ID is given, an array of hashes describing all 182 | notifications. 183 | 184 | If no information is available this will return []. 185 | """ 186 | return Notifier.list(group) 187 | 188 | 189 | if __name__ == '__main__': 190 | Notifier.notify( 191 | "Notification from %s" % __file__, 192 | title='pync Notification', 193 | open='https://github.com/SeTeM/pync', 194 | appIcon='https://assets-cdn.github.com/images/modules/logos_page/Octocat.png' 195 | ) 196 | -------------------------------------------------------------------------------- /pync/vendor/terminal-notifier-2.0.0/README.markdown: -------------------------------------------------------------------------------- 1 | # terminal-notifier 2 | 3 | terminal-notifier is a command-line tool to send macOS User Notifications, 4 | which are available on macOS 10.10 and higher. 5 | 6 | 7 | ## News 8 | 9 | [alerter](https://github.com/vjeantet/alerter) features were merged in terminal-notifier 1.7. This led to some issues and even more issues in the 1.8 release. We decided with [Valère Jeantet](https://github.com/vjeantet) to rollback this merge. 10 | 11 | From now on terminal-notifier won't have the sticky notification feature nor the actions buttons. If you need them please use [alerter](https://github.com/vjeantet/alerter). I also want to follow [semver](http://semver.org) hence this latest version starts at 2.0.0. 12 | 13 | Sticking to two smaller specialized tools will hopefully make them easier to maintain and less error prone. 14 | 15 | 16 | ## Caveats 17 | 18 | * It is currently packaged as an application bundle, because `NSUserNotification` 19 | does not work from a ‘Foundation tool’. [radar://11956694](radar://11956694) 20 | 21 | * If you intend to package terminal-notifier with your app to distribute it on the Mac App Store, please use 1.5.2; version 1.6.0+ uses a private method override, which is not allowed in the App Store Guidelines. 22 | 23 | * If you're using macOS < 10.10 you should use terminal-notifier 1.6.3. 24 | 25 | * If you're looking for sticky notifications or more actions on a notification please use [alerter](https://github.com/vjeantet/alerter) 26 | 27 | ## Download 28 | 29 | Prebuilt binaries are available from the 30 | [releases section](https://github.com/julienXX/terminal-notifier/releases). 31 | 32 | Or if you want to use this from 33 | [Ruby](https://github.com/julienXX/terminal-notifier/tree/master/Ruby), you can 34 | install it through RubyGems: 35 | 36 | ``` 37 | $ [sudo] gem install terminal-notifier 38 | ``` 39 | 40 | You can also install it via [Homebrew](https://github.com/mxcl/homebrew): 41 | ``` 42 | $ brew install terminal-notifier 43 | ``` 44 | 45 | ## Usage 46 | 47 | ``` 48 | $ ./terminal-notifier.app/Contents/MacOS/terminal-notifier -[message|group|list] [VALUE|ID|ID] [options] 49 | ``` 50 | 51 | In order to use terminal-notifier, you have to call the binary _inside_ the 52 | application bundle. 53 | 54 | The Ruby gem, which wraps this tool, _does_ have a bin wrapper. If installed 55 | you can simply do: 56 | 57 | ``` 58 | $ terminal-notifier -[message|group|list] [VALUE|ID|ID] [options] 59 | ``` 60 | 61 | This will obviously be a bit slower than using the tool without the wrapper. 62 | 63 | 64 | ### Example Uses 65 | 66 | Display piped data with a sound: 67 | ``` 68 | $ echo 'Piped Message Data!' | terminal-notifier -sound default 69 | ``` 70 | 71 | ![Example 1](assets/Example_1.png) 72 | 73 | Use a custom icon: 74 | ``` 75 | $ terminal-notifier -title ProjectX -subtitle "new tag detected" -message "Finished" -appIcon http://vjeantet.fr/images/logo.png 76 | ``` 77 | 78 | ![Example 3](assets/Example_3.png) 79 | 80 | Open an URL when the notification is clicked: 81 | ``` 82 | $ terminal-notifier -title '💰' -message 'Check your Apple stock!' -open 'http://finance.yahoo.com/q?s=AAPL' 83 | ``` 84 | 85 | ![Example 4](assets/Example_4.png) 86 | 87 | Open an app when the notification is clicked: 88 | ``` 89 | $ terminal-notifier -group 'address-book-sync' -title 'Address Book Sync' -subtitle 'Finished' -message 'Imported 42 contacts.' -activate 'com.apple.AddressBook' 90 | ``` 91 | 92 | ![Example 5](assets/Example_5.png) 93 | 94 | 95 | ### Options 96 | 97 | At a minimum, you must specify either the `-message` , the `-remove`, or the 98 | `-list` option. 99 | 100 | ------------------------------------------------------------------------------- 101 | 102 | `-message VALUE` **[required]** 103 | 104 | The message body of the notification. 105 | 106 | If you pipe data into terminal-notifier, you can omit this option, 107 | and the piped data will become the message body instead. 108 | 109 | ------------------------------------------------------------------------------- 110 | 111 | `-title VALUE` 112 | 113 | The title of the notification. This defaults to ‘Terminal’. 114 | 115 | ------------------------------------------------------------------------------- 116 | 117 | `-subtitle VALUE` 118 | 119 | The subtitle of the notification. 120 | 121 | ------------------------------------------------------------------------------- 122 | 123 | `-sound NAME` 124 | 125 | Play the `NAME` sound when the notification appears. 126 | Sound names are listed in Sound Preferences. 127 | 128 | Use the special `NAME` “default” for the default notification sound. 129 | 130 | ------------------------------------------------------------------------------- 131 | 132 | `-group ID` 133 | 134 | Specifies the notification’s ‘group’. For any ‘group’, only _one_ 135 | notification will ever be shown, replacing previously posted notifications. 136 | 137 | A notification can be explicitly removed with the `-remove` option (see 138 | below). 139 | 140 | Example group IDs: 141 | 142 | * The sender’s name (to scope the notifications by tool). 143 | * The sender’s process ID (to scope the notifications by a unique process). 144 | * The current working directory (to scope notifications by project). 145 | 146 | ------------------------------------------------------------------------------- 147 | 148 | `-remove ID` **[required]** 149 | 150 | Remove a previous notification from the `ID` ‘group’, if one exists. 151 | 152 | Use the special `ID` “ALL” to remove all messages. 153 | 154 | ------------------------------------------------------------------------------- 155 | 156 | `-list ID` **[required]** 157 | 158 | Lists details about the specified ‘group’ `ID`. 159 | 160 | Use the special `ID` “ALL” to list details about all currently active messages. 161 | 162 | The output of this command is tab-separated, which makes it easy to parse. 163 | 164 | ------------------------------------------------------------------------------- 165 | 166 | `-activate ID` 167 | 168 | Activate the application specified by `ID` when the user clicks the 169 | notification. 170 | 171 | You can find the bundle identifier (`CFBundleIdentifier`) of an application in its `Info.plist` file 172 | _inside_ the application bundle. 173 | 174 | Examples application IDs are: 175 | 176 | * `com.apple.Terminal` to activate Terminal.app 177 | * `com.apple.Safari` to activate Safari.app 178 | 179 | ------------------------------------------------------------------------------- 180 | 181 | `-sender ID` 182 | 183 | Fakes the sender application of the notification. This uses the specified 184 | application’s icon, and will launch it when the notification is clicked. 185 | 186 | Using this option fakes the sender application, so that the notification system 187 | will launch that application when the notification is clicked. Because of this 188 | it is important to note that you cannot combine this with options like 189 | `-execute` and `-activate` which depend on the sender of the notification to be 190 | ‘terminal-notifier’ to perform its work. 191 | 192 | For information on the `ID`, see the `-activate` option. 193 | 194 | ------------------------------------------------------------------------------- 195 | 196 | `-appIcon PATH` 197 | 198 | Specify an image `PATH` to display instead of the application icon. 199 | 200 | **WARNING: This option is subject to change, since it relies on a private method.** 201 | 202 | ------------------------------------------------------------------------------- 203 | 204 | `-contentImage PATH` 205 | 206 | Specify an image `PATH` to attach inside of the notification. 207 | 208 | **WARNING: This option is subject to change since it relies on a private method.** 209 | 210 | ------------------------------------------------------------------------------- 211 | 212 | `-open URL` 213 | 214 | Open `URL` when the user clicks the notification. This can be a web or file URL, 215 | or any custom URL scheme. 216 | 217 | ------------------------------------------------------------------------------- 218 | 219 | `-execute COMMAND` 220 | 221 | Run the shell command `COMMAND` when the user clicks the notification. 222 | 223 | ------------------------------------------------------------------------------- 224 | 225 | `-ignoreDnD` 226 | 227 | Ignore Do Not Disturb settings and unconditionally show the notification. 228 | 229 | **WARNING: This option is subject to change since it relies on a private method.** 230 | 231 | ## License 232 | 233 | All the works are available under the MIT license. **Except** for 234 | ‘Terminal.icns’, which is a copy of Apple’s Terminal.app icon and as such is 235 | copyright of Apple. 236 | 237 | Copyright (C) 2012-2017 Eloy Durán , Julien Blanchard 238 | 239 | 240 | Permission is hereby granted, free of charge, to any person obtaining a copy of 241 | this software and associated documentation files (the "Software"), to deal in 242 | the Software without restriction, including without limitation the rights to 243 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 244 | of the Software, and to permit persons to whom the Software is furnished to do 245 | so, subject to the following conditions: 246 | 247 | The above copyright notice and this permission notice shall be included in all 248 | copies or substantial portions of the Software. 249 | 250 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 251 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 252 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 253 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 254 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 255 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 256 | SOFTWARE. 257 | --------------------------------------------------------------------------------