This commit is contained in:
Daniel Langbein 2021-07-22 16:20:03 +02:00
parent 1183b6fc23
commit 6db2e1a70c
9 changed files with 83 additions and 25 deletions

2
.gitignore vendored
View File

@ -5,4 +5,4 @@
/__pycache__/
/dist/
/src/de_p1st_execNotify.egg-info/
/src/de.p1st.exec_notify.egg-info/

1
.idea/execNotify.iml generated
View File

@ -6,6 +6,7 @@
<excludeFolder url="file://$MODULE_DIR$/dist" />
<excludeFolder url="file://$MODULE_DIR$/src/de_p1st_execNotify.egg-info" />
<excludeFolder url="file://$MODULE_DIR$/mail" />
<excludeFolder url="file://$MODULE_DIR$/src/de.p1st.exec_notify.egg-info" />
</content>
<orderEntry type="jdk" jdkName="Python 3.9 (venv39-2)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />

View File

@ -13,8 +13,8 @@
<option name="ADD_CONTENT_ROOTS" value="false" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/de/p1st/exec_notify/execNotify" />
<option name="PARAMETERS" value="ls $USER" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/de/p1st/exec_notify/execNotify.py" />
<option name="PARAMETERS" value="ls /non/existent/file" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />

View File

@ -13,7 +13,7 @@
<option name="ADD_CONTENT_ROOTS" value="false" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/de/p1st/exec_notify/notify" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/src/de/p1st/exec_notify/notify.py" />
<option name="PARAMETERS" value="someSubject someBody-123" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />

View File

@ -1,14 +1,29 @@
# execNotify
* Send email notification if command fails with [execNotify](src/de/p1st/exec_notify/execNotify).
* Send unconditional notifications with [notify](src/de/p1st/exec_notify/notify).
* Send email notification if command fails with [de-p1st-execNotify](src/de/p1st/exec_notify/execNotify.py).
* Send unconditional notifications with [de-p1st-notify](src/de/p1st/exec_notify/notify.py).
## Installation
Create a _venv_ and install the module from TestPyPI:
More detailed instructions about _venv_ can be found at [https://docs.python.org/3/library/venv.html](https://docs.python.org/3/library/venv.html)
Create a _venv_:
```shell
python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps de-p1st-execNotify
python3 -m venv ~/execNotify/venv
```
Activate the venv:
```shell
source ~/execNotify/venv/bin/activate
# echo "VIRTUAL_ENV=${VIRTUAL_ENV}"
```
Option A: Install the module from TestPyPI:
```shell
python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps --upgrade de-p1st-execNotify
```
The above command uses the parameter `--no-deps`:
@ -18,6 +33,18 @@ The above command uses the parameter `--no-deps`:
> doesnt have any dependencies, its a good practice to avoid installing dependencies when
> using TestPyPI.
Option B: Install from local directory
```shell
python3 -m pip install ~/Downloads/git/execNotify/
```
(Optionally) list installed modules:
```shell
pip list
```
## Configuration
Create configuration file `/etc/execNotify/cfg.ini`.
@ -29,32 +56,32 @@ For the required fields, see [./etc/execNotify/cfg.ini.example](etc/execNotify/c
### Usage of execNotify
Add `execNotify` in front of your command to execute.
Add `de-p1st-execNotify` in front of your command to execute.
You can pipe into `execNotify` but **not** from `execNotify`
You can pipe into `de-p1st-execNotify` but **not** from `de-p1st-execNotify`
as the output gets modified.
**Example:**
`execNotify ls /non/existent/file` will mail you the exit code, stdout and stderr of `ls /non/existent/file`
`de-p1st-execNotify ls /non/existent/file` will mail you the exit code, stdout and stderr of `ls /non/existent/file`
### Usage of notify
Send stdout via mail:
`echo "Hello world!" | notify`
`echo "Hello world!" | de-p1st-notify`
Send stdout and stderr via mail:
`echo "Hello world!" 2>&1 | notify`
`echo "Hello world!" 2>&1 | de-p1st-notify`
Send stdout and specify an optional email subject:
`echo "Hello world!" | notify "someSubject"`
`echo "Hello world!" | de-p1st-notify "someSubject"`
Send message without using a pipe:
`notify "someSubject" "Hello World! What's up?"`
`de-p1st-notify "someSubject" "Hello World! What's up?"`
## Development
@ -62,12 +89,15 @@ Send message without using a pipe:
When started with environment variable `DE_P1ST_EXEC_NOTIFY` set,
then the configuration file is read from [./etc/execNotify/cfg.ini](etc/execNotify/cfg.ini).
### Testing
See heading "Installation" above with steps to locally install this module.
### Uploading to TestPyPI
More detailed instructions can be found at https://packaging.python.org/tutorials/packaging-projects/
More detailed instructions can be found at [https://packaging.python.org/tutorials/packaging-projects/](https://packaging.python.org/tutorials/packaging-projects/)
0) Set up a _venv_
1) Develop and test locally
1) Set up a _venv_
2) Increase/Adjust `[metadata][version]` in [setup.cfg](setup.cfg)
3) Install the `build` and `twine` modules to your _venv_.
4) Next generate a [distribution archive](https://packaging.python.org/tutorials/packaging-projects/#generating-distribution-archives):

View File

@ -3,8 +3,8 @@
# https://pypi.org/classifiers/
[metadata]
name = de-p1st-execNotify
version = 0.0.2
name = de.p1st.exec_notify
version = 0.1.0
author = Daniel Langbein
author_email = daniel@systemli.org
description = Send mail with process output
@ -14,10 +14,16 @@ url = https://codeberg.org/langfingaz/execNotify
project_urls =
Bug Tracker = https://codeberg.org/langfingaz/execNotify/issues
classifiers =
Development Status :: 4 - Beta
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
Operating System :: Unix
[options.entry_points]
console_scripts=
de-p1st-execNotify = de.p1st.exec_notify.execNotify:main
de-p1st-notify = de.p1st.exec_notify.notify:main
[options]
package_dir =
= src

View File

@ -1,3 +1,4 @@
import sys
from pathlib import Path, PosixPath
import configparser
@ -5,23 +6,43 @@ from de.p1st.exec_notify.lib import util
def getHostAndPort():
return config['mail']['host'], config['mail']['port']
try:
return config['mail']['host'], config['mail']['port']
except Exception as e:
print(f'execNotify>> Could not read value [mail][host] from {_getCfgFile()}', file=sys.stderr)
exit(1)
def getPassword():
return config['mail']['password']
try:
return config['mail']['password']
except Exception as e:
print(f'execNotify>> Could not read value [mail][password] from {_getCfgFile()}', file=sys.stderr)
exit(1)
def getFrom():
return config['mail']['from'] # used for mail login as well
try:
return config['mail']['from'] # used for mail login as well
except Exception as e:
print(f'execNotify>> Could not read value [mail][from] from {_getCfgFile()}', file=sys.stderr)
exit(1)
def getTo():
return config['mail']['to']
try:
return config['mail']['to']
except Exception as e:
print(f'execNotify>> Could not read value [mail][to] from {_getCfgFile()}', file=sys.stderr)
exit(1)
def getMailDir() -> Path:
return Path(config['file']['maildir'])
try:
return Path(config['file']['maildir'])
except Exception as e:
print(f'execNotify>> Could not read value [file][maildir] from {_getCfgFile()}', file=sys.stderr)
exit(1)
def _getCfgFile() -> Path: