Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for general notifications #65

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
snapraid-runner.conf
__pycache__
.idea
*.pyc
build
dist
venv
*.egg-info*
.vscode/settings.json
snapraid.log
33 changes: 26 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Snapraid Runner Script
# Snapraid Runner Package

This script runs snapraid and sends its output to the console, a log file and
This python package runs snapraid and sends its output to the console, a log file and
via email. All this is configurable.

It can be run manually, but its main purpose is to be run via cronjob/windows
Expand All @@ -12,14 +12,17 @@ It supports Windows, Linux and macOS and requires at least python3.7.
* If you don’t already have it, download and install
[the latest python version](https://www.python.org/downloads/).
* Download [the latest release](https://github.com/Chronial/snapraid-runner/releases)
of this script and extract it anywhere or clone this repository via git.
of this package.
* Install the release with pip via `python3 -m pip install snapraid-runner-x.x.tar.gz` on Linux or `py -3 -m pip install snapraid-runner-x.x.tar.gz` on Windows
* Copy/rename the `snapraid-runner.conf.example` to `snapraid-runner.conf` and
edit its contents. You need to at least configure `snapraid.executable` and
`snapraid.config`.
* [The wiki](https://github.com/Chronial/snapraid-runner/wiki/How-to-use-snapraid-runner-with-gmail)
has details on how to use gmail for sending mail.
* Run the script via `python3 snapraid-runner.py` on Linux or
`py -3 snapraid-runner.py` on Windows.
* Run the script via `snapraid-runner` command on Linux or Windows.

## Uninstalling
* To uninstall simply run `python3 -m pip uninstall snapraid-runner` on Linux or `py -3 -m pip uninstall snapraid-runner`

## Features
* Runs `diff` before `sync` to see how many files were deleted and aborts if
Expand All @@ -29,8 +32,8 @@ It supports Windows, Linux and macOS and requires at least python3.7.
* Can run `scrub` after `sync`

## Scope of this project and contributions
Snapraid-runner is supposed to be a small tool with clear focus. It should not
have any dependencies to keep installation trivial. I always welcome bugfixes
Snapraid-runner is supposed to be a small tool with clear focus. It should have
minimal dependencies to keep installation trivial. I always welcome bugfixes
and contributions, but be aware that I will not merge new features that I feel
do not fit the core purpose of this tool.

Expand Down Expand Up @@ -64,3 +67,19 @@ feature you are missing, you can have a look

### v0.1 (16 Feb 2014)
* Initial release


# Developers
To install local build to virtual environment:
* `python3 -m pip install build`
* `python3 -m build`
* `python3 -m venv venv`
* `source venv/bin/activate`
* `python3 -m pip install dist/snapraid-runner-x.x.tar.gz`

# Installing
Install from pypi:
* `python3 -m pip install snapraid_runner``
Install from release:
* download release from https://github.com/Chronial/snapraid-runner/releases
* install release: `python3 -m pip install snapraid-runner-x.x.tar.gz`
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
18 changes: 18 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[metadata]
name = snapraid_runner
version = attr: snapraid_runner.VERSION
long_description = file: README.md, LICENSE.txt
classifiers =
Programming Language :: Python :: 3

[options]
zip_safe = False
include_package_data = True
packages = snapraid_runner
python_requires = >=3.7
install_requires =
apprise

[options.entry_points]
console_scripts =
snapraid-runner = snapraid_runner:main
6 changes: 6 additions & 0 deletions snapraid-runner.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,9 @@ enabled = false
plan = 12
; minimum block age (in days) for scrubbing. Only used with percentage plans
older-than = 10

[notifications]
; when to send notifications, comma-separated list of [success, error]
sendon = success,error
; https://github.com/caronc/apprise for full list of supported services
services = mailto://{user}:{password}@hotmail.com,slack://TokenA/TokenB/TokenC/
52 changes: 50 additions & 2 deletions snapraid-runner.py → snapraid_runner/SnapraidRunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,59 @@ def send_email(success):
msg.as_string())
server.quit()

def send_notification(success):
import apprise
from email.mime.text import MIMEText
from email import charset

ap_asset = apprise.AppriseAsset()
apobj = apprise.Apprise(asset=ap_asset)

for url in config["notifications"]["services"]:
if not apobj.add(url):
logging.error('\'%s\' is an invalid AppRise URL.' % (url))

if len(config["notifications"]["services"]) == 0:
logging.error("Failed to send email because no notification services are set")
return

# use quoted-printable instead of the default base64
charset.add_charset("utf-8", charset.SHORTEST, charset.QP)
if success:
body = "SnapRAID job completed successfully:\n\n\n"
else:
body = "Error during SnapRAID job:\n\n\n"

log = email_log.getvalue()
maxsize = config['email'].get('maxsize', 500) * 1024
if maxsize and len(log) > maxsize:
cut_lines = log.count("\n", maxsize // 2, -maxsize // 2)
log = (
"NOTE: Log was too big for email and was shortened\n\n" +
log[:maxsize // 2] +
"[...]\n\n\n --- LOG WAS TOO BIG - {} LINES REMOVED --\n\n\n[...]".format(
cut_lines) +
log[-maxsize // 2:])
body += log

title = config["email"]["subject"] + \
(" SUCCESS" if success else " ERROR")

apobj.notify(body=body, title=title)



def finish(is_success):
if ("error", "success")[is_success] in config["email"]["sendon"]:
try:
send_email(is_success)
except Exception:
logging.exception("Failed to send email")
if ("error", "success")[is_success] in config["notifications"]["sendon"]:
try:
send_notification(is_success)
except Exception:
logging.exception("Failed to send notifications")
if is_success:
logging.info("Run finished successfully")
else:
Expand All @@ -133,7 +179,7 @@ def load_config(args):
global config
parser = configparser.RawConfigParser()
parser.read(args.conf)
sections = ["snapraid", "logging", "email", "smtp", "scrub"]
sections = ["snapraid", "logging", "email", "smtp", "scrub", "notifications"]
config = dict((x, defaultdict(lambda: "")) for x in sections)
for section in parser.sections():
for (k, v) in parser.items(section):
Expand All @@ -154,6 +200,7 @@ def load_config(args):
config["scrub"]["enabled"] = (config["scrub"]["enabled"].lower() == "true")
config["email"]["short"] = (config["email"]["short"].lower() == "true")
config["snapraid"]["touch"] = (config["snapraid"]["touch"].lower() == "true")
config["notifications"]["services"] = config["notifications"]["services"].split(',')

# Migration
if config["scrub"]["percentage"]:
Expand Down Expand Up @@ -311,4 +358,5 @@ def run():
finish(True)


main()
if __name__ == "__main__":
main()
3 changes: 3 additions & 0 deletions snapraid_runner/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .SnapraidRunner import main

VERSION = '0.6'