├── _config.yml ├── pynotificator ├── _version.py ├── __main__.py └── __init__.py ├── setup.py ├── assets ├── logo.afdesign └── logo.svg ├── docs ├── index.rst ├── Makefile ├── installation.rst ├── conf.py ├── make.bat ├── pynotificator.rst └── quickstart.rst ├── requirements.txt ├── setup.cfg ├── LICENSE ├── README.md └── .gitignore /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /pynotificator/_version.py: -------------------------------------------------------------------------------- 1 | __version__ = '1.0.1' 2 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | setup() 3 | -------------------------------------------------------------------------------- /assets/logo.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/higurashi-takuto/pynotificator/HEAD/assets/logo.afdesign -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | PyNotificator Documentation 2 | ########################### 3 | 4 | .. include:: quickstart.rst 5 | 6 | Index 7 | ===== 8 | 9 | .. toctree:: 10 | :maxdepth: 4 11 | 12 | installation 13 | pynotificator 14 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | alabaster==0.7.12 2 | Babel==2.8.0 3 | bleach==3.1.5 4 | certifi==2020.4.5.1 5 | chardet==3.0.4 6 | docutils==0.16 7 | idna==2.9 8 | imagesize==1.2.0 9 | Jinja2==2.11.2 10 | keyring==21.2.1 11 | MarkupSafe==1.1.1 12 | packaging==20.4 13 | pkginfo==1.5.0.1 14 | Pygments==2.6.1 15 | pyparsing==2.4.7 16 | pytz==2020.1 17 | readme-renderer==26.0 18 | requests==2.23.0 19 | requests-toolbelt==0.9.1 20 | six==1.15.0 21 | snowballstemmer==2.0.0 22 | Sphinx==3.0.4 23 | sphinx-rtd-theme==0.4.3 24 | sphinxcontrib-applehelp==1.0.2 25 | sphinxcontrib-devhelp==1.0.2 26 | sphinxcontrib-htmlhelp==1.0.3 27 | sphinxcontrib-jsmath==1.0.1 28 | sphinxcontrib-qthelp==1.0.3 29 | sphinxcontrib-serializinghtml==1.1.4 30 | tqdm==4.46.1 31 | twine==3.1.1 32 | urllib3==1.25.9 33 | webencodings==0.5.1 34 | -------------------------------------------------------------------------------- /docs/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ############ 3 | 4 | Basic Installation 5 | ================== 6 | 7 | PyNotificator is distributed on `PyPI `_. 8 | 9 | macOS and Linux Installation 10 | ---------------------------- 11 | 12 | :: 13 | 14 | $ pip install pynotificator 15 | 16 | Windows Installation 17 | -------------------- 18 | 19 | If you are using Windows, you need an option. 20 | 21 | :: 22 | 23 | $ pip install pynotificator[win] 24 | 25 | 26 | Developing Installation 27 | ======================= 28 | 29 | PyNotificator repository is distributed on `GitHub `_. 30 | 31 | Build from Source 32 | ----------------- 33 | 34 | :: 35 | 36 | $ git clone https://github.com/higurashi-takuto/pynotificator.git 37 | $ cd pynotificator 38 | $ pip install -e . 39 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | import pynotificator 2 | import sphinx_rtd_theme 3 | 4 | project = 'PyNotificator' 5 | copyright = '2020, higurashi-takuto' 6 | author = 'higurashi-takuto' 7 | version = pynotificator.__version__ 8 | release = pynotificator.__version__ 9 | 10 | extensions = ['sphinx.ext.napoleon', 'sphinx_rtd_theme'] 11 | 12 | # templates_path = ['_templates'] 13 | 14 | language = 'en' 15 | 16 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 17 | 18 | html_theme = 'sphinx_rtd_theme' 19 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 20 | 21 | # html_static_path = ['_static'] 22 | 23 | html_sidebars = { 24 | '**': [ 25 | 'relations.html', # needs 'show_related': True theme option to display 26 | 'about.html', 27 | 'navigation.html', 28 | 'searchbox.html', 29 | ] 30 | } 31 | 32 | # Docstring 33 | autodoc_member_order = 'bysource' 34 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = pynotificator 3 | version = 1.0.1 4 | url = https://github.com/higurashi-takuto/pynotificator 5 | author = higurashi-takuto 6 | author_email = contact@hgrs.me 7 | license = MIT 8 | license_file = LICENSE 9 | description = pynotificator: Easily send notifications from Python 10 | long_description = file: README.md 11 | long_description_content_type = text/markdown 12 | 13 | [options] 14 | zip_safe = False 15 | packages = find: 16 | install_requires = 17 | requests 18 | 19 | [options.extras_require] 20 | win = win10toast 21 | 22 | [options.entry_points] 23 | console_scripts = 24 | beep-notify = pynotificator.__main__:beep_notify 25 | desktop-notify = pynotificator.__main__:desktop_notify 26 | slack-notify = pynotificator.__main__:slack_notify 27 | discord-notify = pynotificator.__main__:discord_notify 28 | line-notify = pynotificator.__main__:line_notify -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/pynotificator.rst: -------------------------------------------------------------------------------- 1 | PyNotificator Reference 2 | ####################### 3 | 4 | Index 5 | ===== 6 | 7 | Exception 8 | --------- 9 | 10 | - `NotificationError <#pynotificator.NotificationError>`_ 11 | 12 | Superclass 13 | ---------- 14 | 15 | - `BaseNotification <#pynotificator.BaseNotification>`_ 16 | - `OSSpecificNotification <#pynotificator.OSSpecificNotification>`_ 17 | - `MessageNotification <#pynotificator.MessageNotification>`_ 18 | - `WebhookNotification <#pynotificator.WebhookNotification>`_ 19 | - `TokenNotification <#pynotificator.TokenNotification>`_ 20 | 21 | Subclass 22 | -------- 23 | 24 | - `BeepNotification <#pynotificator.BeepNotification>`_ 25 | - `DesktopNotification <#pynotificator.DesktopNotification>`_ 26 | - `SlackNotification <#pynotificator.SlackNotification>`_ 27 | - `DiscordNotification <#pynotificator.DiscordNotification>`_ 28 | - `LineNotification <#pynotificator.LineNotification>`_ 29 | 30 | Reference 31 | ========= 32 | 33 | .. automodule:: pynotificator 34 | :members: 35 | :undoc-members: 36 | :show-inheritance: 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2009 Type Supply LLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /docs/quickstart.rst: -------------------------------------------------------------------------------- 1 | Quick Start 2 | =========== 3 | 4 | Installation 5 | ------------ 6 | 7 | Install with pip. :: 8 | 9 | $ pip install pynotificator 10 | 11 | If you are using Windows, you need an option: :code:`pip install pynotificator[win]`. 12 | 13 | Python and Command Line Tools 14 | ----------------------------- 15 | 16 | You can use command line tools. 17 | 18 | Beep 19 | ^^^^ 20 | 21 | :: 22 | 23 | # Python 24 | from pynotificator import BeepNotification 25 | bn = BeepNotification(3) 26 | bn.notify() 27 | 28 | # Command Line Tools 29 | $ beep-notify -t 3 30 | 31 | 32 | Desktop 33 | ^^^^^^^ 34 | 35 | :: 36 | 37 | # Python 38 | from pynotificator import DesktopNotification 39 | dn = DesktopNotification('Hello', title='PyNotificator', subtitle='Notify') 40 | dn.notify() 41 | 42 | # Command Line Tools 43 | $ desktop-notify -m Hello -t PyNotificator -s Notify 44 | 45 | Slack 46 | ^^^^^ 47 | 48 | :: 49 | 50 | # Python 51 | from pynotificator import SlackNotification 52 | sn = SlackNotification('PyNotificator', 'https://hooks.slack.com/services/xxx') 53 | sn.notify() 54 | 55 | # Command Line Tools 56 | $ slack-notify -m PyNotificator https://hooks.slack.com/services/xxx 57 | 58 | Discord 59 | ^^^^^^^ 60 | 61 | :: 62 | 63 | # Python 64 | from pynotificator import DiscordNotification 65 | dn = DiscordNotification('PyNotificator', 'https://discordapp.com/api/webhooks/xxx') 66 | dn.notify() 67 | 68 | # Command Line Tools 69 | $ discord-notify -m PyNotificator https://discordapp.com/api/webhooks/xxx 70 | 71 | LINE 72 | ^^^^ 73 | 74 | :: 75 | 76 | # Python 77 | from pynotificator import LineNotification 78 | ln = LineNotification('PyNotificator', 'xxx') 79 | ln.notify() 80 | 81 | # Command Line Tools 82 | $ line-notify -m PyNotificator xxx 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyNotificator 2 | 3 | [HomePage](https://higurashi-takuto.github.io/pynotificator/) / [Documentation](https://pynotificator.readthedocs.io/en/latest/) / [PyPI](https://pypi.org/project/pynotificator/) 4 | 5 | ## Quick Start 6 | 7 | ### Installation 8 | 9 | Install with pip. 10 | ``` 11 | $ pip install pynotificator 12 | ``` 13 | 14 | If you are using Windows, you need an option: `pip install pynotificator[win]`. 15 | 16 | ### Python and Command Line Tools 17 | 18 | You can use command line tools. 19 | 20 | #### Beep 21 | ``` 22 | # Python 23 | from pynotificator import BeepNotification 24 | bn = BeepNotification(3) 25 | bn.notify() 26 | 27 | # Command Line Tools 28 | $ beep-notify -t 3 29 | ``` 30 | 31 | #### Desktop 32 | ``` 33 | # Python 34 | from pynotificator import DesktopNotification 35 | dn = DesktopNotification('Hello', title='PyNotificator', subtitle='Notify') 36 | dn.notify() 37 | 38 | # Command Line Tools 39 | $ desktop-notify -m Hello -t PyNotificator -s Notify 40 | ``` 41 | 42 | #### Slack 43 | ``` 44 | # Python 45 | from pynotificator import SlackNotification 46 | sn = SlackNotification('PyNotificator', 'https://hooks.slack.com/services/xxx') 47 | sn.notify() 48 | 49 | # Command Line Tools 50 | $ slack-notify -m PyNotificator https://hooks.slack.com/services/xxx 51 | ``` 52 | 53 | #### Discord 54 | ``` 55 | # Python 56 | from pynotificator import DiscordNotification 57 | dn = DiscordNotification('PyNotificator', 'https://discordapp.com/api/webhooks/xxx') 58 | dn.notify() 59 | 60 | # Command Line Tools 61 | $ discord-notify -m PyNotificator https://discordapp.com/api/webhooks/xxx 62 | ``` 63 | 64 | #### LINE 65 | ``` 66 | # Python 67 | from pynotificator import LineNotification 68 | ln = LineNotification('PyNotificator', 'xxx') 69 | ln.notify() 70 | 71 | # Command Line Tools 72 | $ line-notify -m PyNotificator xxx 73 | ``` 74 | 75 | ## License 76 | [MIT License](https://raw.githubusercontent.com/higurashi-takuto/pynotificator/master/LICENSE) 77 | 78 | ## Author 79 | [higurashi-takuto](https://hgrs.me/) 80 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | test.py 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | pip-wheel-metadata/ 26 | share/python-wheels/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | MANIFEST 31 | 32 | # PyInstaller 33 | # Usually these files are written by a python script from a template 34 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 35 | *.manifest 36 | *.spec 37 | 38 | # Installer logs 39 | pip-log.txt 40 | pip-delete-this-directory.txt 41 | 42 | # Unit test / coverage reports 43 | htmlcov/ 44 | .tox/ 45 | .nox/ 46 | .coverage 47 | .coverage.* 48 | .cache 49 | nosetests.xml 50 | coverage.xml 51 | *.cover 52 | *.py,cover 53 | .hypothesis/ 54 | .pytest_cache/ 55 | 56 | # Translations 57 | *.mo 58 | *.pot 59 | 60 | # Django stuff: 61 | *.log 62 | local_settings.py 63 | db.sqlite3 64 | db.sqlite3-journal 65 | 66 | # Flask stuff: 67 | instance/ 68 | .webassets-cache 69 | 70 | # Scrapy stuff: 71 | .scrapy 72 | 73 | # Sphinx documentation 74 | docs/_build/ 75 | 76 | # PyBuilder 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | .python-version 88 | 89 | # pipenv 90 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 91 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 92 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 93 | # install all needed dependencies. 94 | #Pipfile.lock 95 | 96 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 97 | __pypackages__/ 98 | 99 | # Celery stuff 100 | celerybeat-schedule 101 | celerybeat.pid 102 | 103 | # SageMath parsed files 104 | *.sage.py 105 | 106 | # Environments 107 | .env 108 | .venv 109 | env/ 110 | venv/ 111 | ENV/ 112 | env.bak/ 113 | venv.bak/ 114 | 115 | # Spyder project settings 116 | .spyderproject 117 | .spyproject 118 | 119 | # Rope project settings 120 | .ropeproject 121 | 122 | # mkdocs documentation 123 | /site 124 | 125 | # mypy 126 | .mypy_cache/ 127 | .dmypy.json 128 | dmypy.json 129 | 130 | # Pyre type checker 131 | .pyre/ -------------------------------------------------------------------------------- /pynotificator/__main__.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | import pynotificator 4 | 5 | 6 | def beep_notify(): 7 | parser = argparse.ArgumentParser(description='Beep Notification') 8 | parser.add_argument('--times', '-t', type=int, default=1, 9 | help='The number of times of beep sound') 10 | args = parser.parse_args() 11 | 12 | bn = pynotificator.BeepNotification(args.times) 13 | bn.notify() 14 | 15 | 16 | def desktop_notify(): 17 | parser = argparse.ArgumentParser(description='Desktop Notification') 18 | parser.add_argument('--message', '-m', default='PyNotificator', 19 | help='Content of notice') 20 | parser.add_argument('--title', '-t', default='', 21 | help='Title of notice') 22 | parser.add_argument('--subtitle', '-s', default='', 23 | help='Subtitle of notice') 24 | parser.add_argument('--icon', '-i', default='', 25 | help='Icon of notice') 26 | parser.add_argument('--nosound', action='store_true', 27 | help='Disable notification sound') 28 | args = parser.parse_args() 29 | 30 | dn = pynotificator.DesktopNotification( 31 | args.message, args.title, args.subtitle, args.icon, not args.nosound) 32 | dn.notify() 33 | 34 | 35 | def slack_notify(): 36 | parser = argparse.ArgumentParser(description='Slack Notification') 37 | parser.add_argument('--message', '-m', default='PyNotificator', 38 | help='Content of notice') 39 | parser.add_argument('url', help='Incoming Webhook URL') 40 | args = parser.parse_args() 41 | 42 | sn = pynotificator.SlackNotification(args.message, args.url) 43 | sn.notify() 44 | 45 | 46 | def discord_notify(): 47 | parser = argparse.ArgumentParser(description='Discord Notification') 48 | parser.add_argument('--message', '-m', default='PyNotificator', 49 | help='Content of notice') 50 | parser.add_argument('url', help='Discord Webhook URL') 51 | args = parser.parse_args() 52 | 53 | dn = pynotificator.DiscordNotification(args.message, args.url) 54 | dn.notify() 55 | 56 | 57 | def line_notify(): 58 | parser = argparse.ArgumentParser(description='Line Notification') 59 | parser.add_argument('--message', '-m', default='PyNotificator', 60 | help='Content of notice') 61 | parser.add_argument('token', help='LINE Notify token') 62 | args = parser.parse_args() 63 | 64 | ln = pynotificator.LineNotification(args.message, args.token) 65 | ln.notify() 66 | -------------------------------------------------------------------------------- /pynotificator/__init__.py: -------------------------------------------------------------------------------- 1 | import json 2 | import platform 3 | import subprocess 4 | import time 5 | 6 | import requests 7 | 8 | from ._version import __version__ # noqa: F401 9 | 10 | 11 | class NotificationError(Exception): 12 | '''Notification Error''' 13 | pass 14 | 15 | 16 | class BaseNotification: 17 | '''Notification Superclass''' 18 | def set_typed_variable(self, value, specified_type): 19 | '''Check the type and return it. 20 | 21 | Args: 22 | value (Object): Value to check 23 | specified_type (Object): Specified type of value 24 | 25 | Returns: 26 | Object: Checked value 27 | 28 | Raises: 29 | NotificationError: When the types don’t match. 30 | 31 | Examples: 32 | >>> number = set_typed_variable(3, int) 33 | >>> number 34 | 3 35 | >>> string = set_typed_variable('3', int) 36 | NotificationError: can only set int (not "str") 37 | ''' 38 | if isinstance(value, specified_type): 39 | return value 40 | else: 41 | raise NotificationError( 42 | 'can only set ' 43 | f'{specified_type.__name__} ' 44 | f'(not "{value.__class__.__name__}")' 45 | ) 46 | 47 | # Main 48 | def notify(self): 49 | '''Executing the notification 50 | 51 | Raises: 52 | NotImplementedError: When there is no implementation 53 | ''' 54 | raise NotImplementedError() 55 | 56 | 57 | class OSSpecificNotification(BaseNotification): 58 | '''OS-specific notifications 59 | 60 | Attributes: 61 | system (str): OS you are using 62 | ''' 63 | def __init__(self): 64 | self.system = platform.system() 65 | 66 | def darwin_notify(self): 67 | '''Executing macOS notification 68 | 69 | Raises: 70 | NotImplementedError: When there is no implementation 71 | ''' 72 | raise NotImplementedError() 73 | 74 | def linux_notify(self): 75 | '''Executing Linux notification 76 | 77 | Raises: 78 | NotImplementedError: When there is no implementation 79 | ''' 80 | raise NotImplementedError() 81 | 82 | def windows_notify(self): 83 | '''Executing Windows notification 84 | 85 | Raises: 86 | NotImplementedError: When there is no implementation 87 | ''' 88 | raise NotImplementedError() 89 | 90 | def notify(self): 91 | '''Executing the notification 92 | 93 | Raises: 94 | NotificationError: When you use an unsupported OS 95 | ''' 96 | if self.system == 'Darwin': 97 | self.darwin_notify() 98 | elif self.system == 'Linux': 99 | self.linux_notify() 100 | elif self.system == 'Windows': 101 | self.windows_notify() 102 | else: 103 | NotificationError(f'{self.system} is not supported system') 104 | 105 | 106 | class MessageNotification(BaseNotification): 107 | '''Notification with message 108 | 109 | Args: 110 | message (str): Message body 111 | ''' 112 | def __init__(self, message): 113 | self._message = None 114 | self.set_message(message) 115 | 116 | def get_message(self): 117 | return self._message 118 | 119 | def set_message(self, message): 120 | self._message = self.set_typed_variable(message, str) 121 | 122 | message = property(get_message, set_message) 123 | '''str: Message body''' 124 | 125 | 126 | class WebhookNotification(MessageNotification): 127 | '''Webhook notification 128 | 129 | Args: 130 | message (str): Message body 131 | url (str): Webhook URL 132 | ''' 133 | def __init__(self, message, url): 134 | super().__init__(message) 135 | self._url = None 136 | self.set_url(url) 137 | 138 | def get_url(self): 139 | return self._url 140 | 141 | def set_url(self, url): 142 | self._url = self.set_typed_variable(url, str) 143 | 144 | url = property(get_url, set_url) 145 | '''str: Webhook URL''' 146 | 147 | 148 | class TokenNotification(MessageNotification): 149 | '''Token notification 150 | 151 | Args: 152 | message (str): Message body 153 | token (str): Token 154 | ''' 155 | def __init__(self, message, token): 156 | super().__init__(message) 157 | self._token = None 158 | self.set_token(token) 159 | 160 | def get_token(self): 161 | return self._token 162 | 163 | def set_token(self, token): 164 | self._token = self.set_typed_variable(token, str) 165 | 166 | token = property(get_token, set_token) 167 | '''str: Token''' 168 | 169 | 170 | class BeepNotification(OSSpecificNotification): 171 | '''Beep notification 172 | 173 | Args: 174 | times (int): times of beep sound 175 | 176 | Examples: 177 | Usage 178 | >>> bn = BeepNotification(3) 179 | >>> bn.notify() 180 | 181 | Change the times of beep sound 182 | >>> bn.times = 1 183 | >>> bn.notify() 184 | 185 | Command Line Tools 186 | ``$ beep-notify [-h] [--times TIMES]`` 187 | ''' 188 | def __init__(self, times): 189 | super().__init__() 190 | self._times = None 191 | self.set_times(times) 192 | 193 | def get_times(self): 194 | return self._times 195 | 196 | def set_times(self, times): 197 | self._times = self.set_typed_variable(times, int) 198 | 199 | times = property(get_times, set_times) 200 | '''int: times of beep sound''' 201 | 202 | def darwin_notify(self): 203 | cmd = ['osascript', '-e', f'beep {self._times}'] 204 | subprocess.run(cmd) 205 | 206 | def linux_notify(self): 207 | for _ in range(self._times): 208 | cmd = ['xkbbell'] 209 | subprocess.run(cmd) 210 | time.sleep(0.5) 211 | 212 | def windows_notify(self): 213 | for _ in range(self._times): 214 | cmd = ['rundll32', 'user32.dll,MessageBeep'] 215 | subprocess.run(cmd) 216 | time.sleep(0.5) 217 | 218 | 219 | class DesktopNotification(MessageNotification, OSSpecificNotification): 220 | '''Desktop Notification 221 | 222 | Args: 223 | message(str): Message body 224 | title(str): Title 225 | subtitle(str): Subtitle 226 | icon(str): Icon 227 | sound(bool): Presence of sound 228 | 229 | Examples: 230 | Usage 231 | >>> dn = DesktopNotification('Hello', title='PyNotificator') 232 | >>> dn.notify() 233 | 234 | Change the message body 235 | >>> dn.message = 'Change Body' 236 | >>> dn.notify() 237 | 238 | Command Line Tools 239 | ``$ desktop-notify [-h] [--message MESSAGE] 240 | [--title TITLE] [--subtitle SUBTITLE] 241 | [--nosound]`` 242 | ''' 243 | def __init__(self, message, title=None, subtitle=None, 244 | icon=None, sound=True): 245 | MessageNotification.__init__(self, message) 246 | OSSpecificNotification.__init__(self) 247 | self._title = None 248 | self._subtitle = None 249 | self._icon = None 250 | self._sound = None 251 | if title: 252 | self.set_title(title) 253 | if subtitle: 254 | self.set_subtitle(subtitle) 255 | if icon: 256 | self.set_icon(icon) 257 | if sound: 258 | self.set_sound(sound) 259 | 260 | def get_title(self): 261 | return self._title 262 | 263 | def set_title(self, title): 264 | self._title = self.set_typed_variable(title, str) 265 | 266 | def get_subtitle(self): 267 | return self._subtitle 268 | 269 | def set_subtitle(self, subtitle): 270 | self._subtitle = self.set_typed_variable(subtitle, str) 271 | 272 | def get_icon(self): 273 | return self._icon 274 | 275 | def set_icon(self, icon): 276 | self._icon = self.set_typed_variable(icon, str) 277 | 278 | def get_sound(self): 279 | return self._sound 280 | 281 | def set_sound(self, sound): 282 | self._sound = self.set_typed_variable(sound, bool) 283 | 284 | title = property(get_title, set_title) 285 | '''str: Title''' 286 | 287 | subtitle = property(get_subtitle, set_subtitle) 288 | '''str: Subtitle''' 289 | 290 | icon = property(get_icon, set_icon) 291 | '''str: Icon''' 292 | 293 | sound = property(get_sound, set_sound) 294 | '''bool: Presence of sound''' 295 | 296 | def darwin_notify(self): 297 | _message = f'display notification \"{self._message}\"' 298 | _title = '' 299 | if self._title: 300 | _title += f'with title \"{self._title}\" ' 301 | if self._subtitle: 302 | _title += f'subtitle \"{self._subtitle}\"' 303 | _sound = 'sound name \"\"' if self._sound else '' 304 | cmd = ['osascript', '-e', f'{_message} {_title} {_sound}'] 305 | subprocess.run(cmd) 306 | 307 | def linux_notify(self): 308 | if self._title and self._subtitle: 309 | _title = f'{self._title} - {self._subtitle}' 310 | elif self._title: 311 | _title = self._title 312 | elif self._subtitle: 313 | _title = self._subtitle 314 | else: 315 | _title = ' ' 316 | cmd = ['notify-send', _title, self._message] 317 | if self._icon: 318 | cmd.extend(['-i', self._icon]) 319 | subprocess.run(cmd) 320 | 321 | def windows_notify(self): 322 | from win10toast import ToastNotifier 323 | toaster = ToastNotifier() 324 | if self._title and self._subtitle: 325 | _title = f'{self._title} - {self._subtitle}' 326 | elif self._title: 327 | _title = self._title 328 | elif self._subtitle: 329 | _title = self._subtitle 330 | else: 331 | _title = None 332 | toaster.show_toast(_title, 333 | self._message, 334 | icon_path=self._icon, 335 | duration=5) 336 | 337 | 338 | class SlackNotification(WebhookNotification): 339 | '''Slack Notification 340 | 341 | Examples: 342 | Usage 343 | >>> sn = SlackNotification('Hello', 'https://hooks.slack.com/xxx') 344 | >>> sn.notify() 345 | 346 | Change the message body 347 | >>> sn.message = 'Change Body' 348 | >>> sn.notify() 349 | 350 | Command Line Tools 351 | ``$ slack-notify [-h] [--message MESSAGE] url`` 352 | ''' 353 | 354 | def notify(self): 355 | '''Executing the notification''' 356 | data = {'text': self._message} 357 | requests.post(self._url, data=json.dumps(data)) 358 | 359 | 360 | class DiscordNotification(WebhookNotification): 361 | '''Discord Notification 362 | 363 | Examples: 364 | Usage 365 | >>> dn = DiscordNotification('Hello', 'https://discordapp.com/xxx') 366 | >>> dn.notify() 367 | 368 | Change the message body 369 | >>> dn.message = 'Change Body' 370 | >>> dn.notify() 371 | 372 | Command Line Tools 373 | ``$ discord-notify [-h] [--message MESSAGE] url`` 374 | ''' 375 | 376 | def notify(self): 377 | '''Executing the notification''' 378 | data = {'content': self._message} 379 | requests.post( 380 | self._url, 381 | headers={'Content-Type': 'application/json'}, 382 | data=json.dumps(data) 383 | ) 384 | 385 | 386 | class LineNotification(TokenNotification): 387 | '''LINE Notification 388 | 389 | Args: 390 | message(str): Message body 391 | token(str): LINE Notify token 392 | 393 | Examples: 394 | Usage 395 | >>> ln = LineNotification('Hello', 'xxx') 396 | >>> ln.notify() 397 | 398 | Change the message body 399 | >>> ln.message = 'Change Body' 400 | >>> ln.notify() 401 | 402 | Command Line Tools 403 | ``$ line-notify [-h] [--message MESSAGE] token`` 404 | ''' 405 | 406 | def __init__(self, message, token): 407 | super().__init__(message, token) 408 | self.URL = 'https://notify-api.line.me/api/notify' 409 | 410 | def notify(self): 411 | '''Executing the notification''' 412 | headers = {'Authorization': f'Bearer {self._token}'} 413 | params = {'message': self._message} 414 | requests.post( 415 | self.URL, 416 | headers=headers, 417 | params=params 418 | ) 419 | -------------------------------------------------------------------------------- /assets/logo.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------