postprocess - FailureEmail

Share your scripts or request scripts with specific features.
Forum rules
Please keep the forum clean - one topic per script. Questions not related to a specific script should be posted in Support forum.
Post Reply
theparnic
Posts: 28
Joined: 30 Apr 2013, 19:56

postprocess - FailureEmail

Post by theparnic » 06 May 2013, 03:27

I copied most of the EMail post-process script and tweaked it a little to only email on failure. I did this because I want some categories to email me regardless of result and other categories to only email on failure.

Code: Select all

#!/usr/bin/env python
#
# E-Mail post-processing script for NZBGet that notifies on failure only
#
# Copyright (C) 2013 Andrey Prygunkov <hugbug@users.sourceforge.net>
# With modifications by Chris Pickett "Parnic"
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#
# $Revision: 660 $
# $Date: 2013-05-02 15:40:36 -0500 (Thu, 02 May 2013) $
#


##############################################################################
### NZBGET POST-PROCESSING SCRIPT                                          ###

# Send E-Mail notification for failed jobs.
#
# This script sends E-Mail notification when a job has failed.
#
# NOTE: This script requires Python to be installed on your system.

##############################################################################
### OPTIONS                                                       ###

# Email address you want this email to be sent from.
#From="NZBGet" <myaccount@gmail.com>

# Email address you want this email to be sent to.
#To=myaccount@gmail.com

# SMTP server host.
#Server=smtp.gmail.com

# SMTP server port (1-65535).
#Port=25

# Secure communication using TLS/SSL (yes, no).
#Encryption=yes

# SMTP server user name, if required.
#Username=myaccount

# SMTP server password, if required.
#Password=mypass

# Append list of files to the message (yes, no).
#
# Add the list of downloaded files (the content of destination directory).
#FileList=yes

# Append broken-log to the message (yes, no).
#
# Add the content of file _brokenlog.txt. This file contains the list of damaged
# files and the result of par-check/repair. For successful downloads the broken-log
# is usually deleted by cleanup-script and therefore is not sent.
#BrokenLog=yes

# Append post-processing log to the message (yes, no).
#
# Add the post-processing log of active job.
#PostProcessLog=yes

# Report when par repair fails or is skipped (yes, no).
#ReportParFailure=yes

# Report when unpack is skipped (yes, no).
#ReportUnpackSkipped=yes

# Report when unpack fails (yes, no).
#ReportUnpackFailure=yes

### NZBGET POST-PROCESSING SCRIPT                                          ###
##############################################################################


import os
import sys
import datetime
import smtplib
from email.mime.text import MIMEText
try:
        from xmlrpclib import ServerProxy
except ImportError:
        from xmlrpc.client import ServerProxy

# Exit codes used by NZBGet
POSTPROCESS_SUCCESS=93
POSTPROCESS_ERROR=94

# Check if the script is called from nzbget 11.0 or later
if not 'NZBOP_SCRIPTDIR' in os.environ:
        print('*** NZBGet post-processing script ***')
        print('This script is supposed to be called from nzbget (11.0 or later).')
        sys.exit(POSTPROCESS_ERROR)

print('[DETAIL] Script successfully started')
sys.stdout.flush()

required_options = ('NZBPO_FROM', 'NZBPO_TO', 'NZBPO_SERVER', 'NZBPO_PORT', 'NZBPO_ENCRYPTION',
        'NZBPO_USERNAME', 'NZBPO_PASSWORD', 'NZBPO_FILELIST', 'NZBPO_BROKENLOG', 'NZBPO_POSTPROCESSLOG',
        'NZBPO_REPORTPARFAILURE', 'NZBPO_REPORTUNPACKSKIPPED', 'NZBPO_REPORTUNPACKFAILURE')
for     optname in required_options:
        if (not optname in os.environ):
                print('[ERROR] Option %s is missing in configuration file. Please check script settings' % optname[6:])
                sys.exit(POSTPROCESS_ERROR)

# Check par and unpack status for errors.
success=False
report=False
if os.environ['NZBPP_PARSTATUS'] == '1' or os.environ['NZBPP_UNPACKSTATUS'] == '1':
        subject = 'Failure for "%s"' % (os.environ['NZBPP_NZBNAME'])
        text = 'Download of "%s" has failed.' % (os.environ['NZBPP_NZBNAME'])
elif os.environ['NZBPP_PARSTATUS'] == '4':
        subject = 'Damaged for "%s"' % (os.environ['NZBPP_NZBNAME'])
        text = 'Download of "%s" requires par-repair.' % (os.environ['NZBPP_NZBNAME'])
else:
        subject = 'Success for "%s"' % (os.environ['NZBPP_NZBNAME'])
        text = 'Download of "%s" has successfully completed.' % (os.environ['NZBPP_NZBNAME'])
        success=True

#  NZBPP_PARSTATUS    - result of par-check:
#                       0 = not checked: par-check is disabled or nzb-file does
#                           not contain any par-files;
#                       1 = checked and failed to repair;
#                       2 = checked and successfully repaired;
#                       3 = checked and can be repaired but repair is disabled.
#                       4 = par-check needed but skipped (option ParCheck=manual);
parStatus = { '0': 'skipped', '1': 'failed', '2': 'repaired', '3': 'repairable', '4': 'manual' }
text += '\nPar-Status: %s' % parStatus[os.environ['NZBPP_PARSTATUS']]
if os.environ['NZBPO_REPORTPARFAILURE'] == 'yes':
        report = report or os.environ['NZBPP_PARSTATUS'] == '1' or os.environ['NZBPP_PARSTATUS'] == '3' or os.environ['NZBPP_PARSTATUS'] == '4'

#  NZBPP_UNPACKSTATUS - result of unpack:
#                       0 = unpack is disabled or was skipped due to nzb-file
#                           properties or due to errors during par-check;
#                       1 = unpack failed;
#                       2 = unpack successful.
unpackStatus = { '0': 'skipped', '1': 'failed', '2': 'success' }
text += '\nUnpack-Status: %s' % unpackStatus[os.environ['NZBPP_UNPACKSTATUS']]
if os.environ['NZBPO_REPORTUNPACKSKIPPED'] == 'yes':
        report = report or os.environ['NZBPP_UNPACKSTATUS'] == '0'
if os.environ['NZBPO_REPORTUNPACKFAILURE'] == 'yes':
        report = report or os.environ['NZBPP_UNPACKSTATUS'] == '1'

if report:
        # add list of downloaded files
        if os.environ['NZBPO_FILELIST'] == 'yes':
                text += '\n\nFiles:'
                for dirname, dirnames, filenames in os.walk(os.environ['NZBPP_DIRECTORY']):
                        for filename in filenames:
                                text += '\n' + os.path.join(dirname, filename)[len(os.environ['NZBPP_DIRECTORY']) + 1:]

        # add _brokenlog.txt (if exists)
        if os.environ['NZBPO_BROKENLOG'] == 'yes':
                brokenlog = '%s/_brokenlog.txt' % os.environ['NZBPP_DIRECTORY']
                if os.path.exists(brokenlog):
                        text += '\n\nBrokenlog:\n' + open(brokenlog, 'r').read().strip()

        # add post-processing log
        if os.environ['NZBPO_POSTPROCESSLOG'] == 'yes':
                # To get the post-processing log we connect to NZBGet via XML-RPC
                # and call method "postqueue", which returns the list of post-processing job.
                # The first item in the list is current job. This item has a field 'Log',
                # containing an array of log-entries.
                # For more info visit http://nzbget.sourceforge.net/RPC_API_reference

                # First we need to know connection info: host, port and password of NZBGet server.
                # NZBGet passes all configuration options to post-processing script as
                # environment variables.
                host = os.environ['NZBOP_CONTROLIP'];
                port = os.environ['NZBOP_CONTROLPORT'];
                password = os.environ['NZBOP_CONTROLPASSWORD'];

                if host == '0.0.0.0': host = '127.0.0.1'

                # Build an URL for XML-RPC requests
                rpcUrl = 'http://nzbget:%s@%s:%s/xmlrpc' % (password, host, port);

                # Create remote server object
                server = ServerProxy(rpcUrl)

                # Call remote method 'postqueue'. The only parameter tells how many log-entries to return as maximum.
                postqueue = server.postqueue(10000)

                # Get field 'Log' from the first post-processing job
                log = postqueue[0]['Log']

                # Now iterate through entries and save them to message text
                if len(log) > 0:
                        text += '\n\nPost-processing log:';
                        for entry in log:
                                text += '\n%s\t%s\t%s' % (entry['Kind'], datetime.datetime.fromtimestamp(int(entry['Time'])), entry['Text'])

        # Create message
        msg = MIMEText(text)
        msg['Subject'] = subject
        msg['From'] = os.environ['NZBPO_FROM']
        msg['To'] = os.environ['NZBPO_TO']

        # Send message
        print('[DETAIL] Sending E-Mail')
        sys.stdout.flush()
        try:
                smtp = smtplib.SMTP(os.environ['NZBPO_SERVER'], os.environ['NZBPO_PORT'])

                if os.environ['NZBPO_ENCRYPTION'] == 'yes':
                        smtp.starttls()

                if os.environ['NZBPO_USERNAME'] != '' and os.environ['NZBPO_PASSWORD'] != '':
                        smtp.login(os.environ['NZBPO_USERNAME'], os.environ['NZBPO_PASSWORD'])

                smtp.sendmail(os.environ['NZBPO_FROM'], os.environ['NZBPO_TO'], msg.as_string())

                smtp.quit()
        except Exception as err:
                print('[ERROR] %s' % err)
                sys.exit(POSTPROCESS_ERROR)

# All OK, returning exit status 'POSTPROCESS_SUCCESS' (int <93>) to let NZBGet know
# that our script has successfully completed.
sys.exit(POSTPROCESS_SUCCESS)
Attachments
FailureEMail.py
(8.68 KiB) Downloaded 631 times
Last edited by theparnic on 20 May 2013, 04:48, edited 3 times in total.

picardtux
Posts: 71
Joined: 05 Sep 2012, 12:45
Contact:

Re: postprocess - FailureEmail

Post by picardtux » 09 May 2013, 09:26

# Now iterate through entries and save them to message text
if len(log) > 0:
text += '\n\nPost-processing log:';
for entry in log:
text += '\n%s\t%s\t%s' % (entry['Kind'], datetime.datetime.fromtimestamp(int(entry['Time'])), entry['Tex$
in the end what is missing here?

theparnic
Posts: 28
Joined: 30 Apr 2013, 19:56

Re: postprocess - FailureEmail

Post by theparnic » 09 May 2013, 15:07

picardtux wrote:
# Now iterate through entries and save them to message text
if len(log) > 0:
text += '\n\nPost-processing log:';
for entry in log:
text += '\n%s\t%s\t%s' % (entry['Kind'], datetime.datetime.fromtimestamp(int(entry['Time'])), entry['Tex$
in the end what is missing here?
Whoops, thanks for pointing that out. Bad copy/paste from 'nano' on my part :). I've fixed the OP, that line should be:
text += '\n%s\t%s\t%s' % (entry['Kind'], datetime.datetime.fromtimestamp(int(entry['Time'])), entry['Text'])

picardtux
Posts: 71
Joined: 05 Sep 2012, 12:45
Contact:

Re: postprocess - FailureEmail

Post by picardtux » 09 May 2013, 18:40

no problem, I know the problem. ;)
many thanks for the great script :!:

hugbug
Developer & Admin
Posts: 7645
Joined: 09 Sep 2008, 11:58
Location: Germany

Re: postprocess - FailureEmail

Post by hugbug » 10 May 2013, 12:16

Wouldn't it be better to attach the scripts to the post (as file-attachment)? Should be more convenient for download.

There was a restriction on forum that .py and .sh file-extensions were not allowed but I've fixed this.

theparnic
Posts: 28
Joined: 30 Apr 2013, 19:56

Re: postprocess - FailureEmail

Post by theparnic » 11 May 2013, 01:15

hugbug wrote:Wouldn't it be better to attach the scripts to the post (as file-attachment)? Should be more convenient for download.

There was a restriction on forum that .py and .sh file-extensions were not allowed but I've fixed this.
Sounds good. I've attached them.

war59312
Posts: 47
Joined: 12 Feb 2013, 04:52
Location: U.S.A
Contact:

Re: postprocess - FailureEmail

Post by war59312 » 23 Jul 2013, 02:16

Thanks for the edit, was looking to do the same.

SimCom
Posts: 3
Joined: 29 Aug 2014, 12:40

Re: postprocess - FailureEmail

Post by SimCom » 29 Aug 2014, 12:48

I'm using nzbget 14.0-testing-r1103 and the script was sending me "Success" emails when the health was bad on the download and NZBget was marking it as a failure. So, I made some additions to the script and so far seems to be working well. I don't profess to being a programmer by any stretch of the imagination, and I haven't tested this thoroughly. So, if anyone else was having the same problem, here are my additions added to about line 130. It's in the "Check par and upack status for errors" section.

Code: Select all

elif os.environ['NZBPP_TOTALSTATUS'] == 'FAILURE':
         subject = 'Failure for "%s"' % (os.environ['NZBPP_NZBNAME'])
         text = 'Download of "%s" has failed.' % (os.environ['NZBPP_NZBNAME'])
elif os.environ['NZBPP_TOTALSTATUS'] == 'DELETED':
         subject = 'Failure for "%s"' % (os.environ['NZBPP_NZBNAME'])
         text = 'Download of "%s" has failed.' % (os.environ['NZBPP_NZBNAME'])


theparnic
Posts: 28
Joined: 30 Apr 2013, 19:56

Re: postprocess - FailureEmail

Post by theparnic » 29 Aug 2014, 14:55

Thanks, I'll look into that.

killer8
Posts: 45
Joined: 12 Dec 2014, 20:36

Re: postprocess - FailureEmail

Post by killer8 » 12 Dec 2014, 21:35

I can't get it to work. I keep getting the following error even when all config is correct:

Code: Select all

Fri Dec 12 22:30:54 2014	INFO	Executing post-process-script FailureEmail.py for VA-New In The SLAM!40 Week 49-2014
Fri Dec 12 22:30:54 2014	DETAIL	FailureEmail: Script successfully started
Fri Dec 12 22:30:54 2014	WARNING	Request received on port 6789 from 127.0.0.1, but username or password invalid (nzbget:password)
Fri Dec 12 22:30:54 2014	INFO	FailureEmail: Traceback (most recent call last):
Fri Dec 12 22:30:54 2014	INFO	FailureEmail:   File "/share/MD0_DATA/.qpkg/NZBGet/nzbget/share/nzbget/scripts/FailureEmail.py", line 197, in <module>
Fri Dec 12 22:30:54 2014	INFO	FailureEmail:     postqueue = server.postqueue(10000)
Fri Dec 12 22:30:54 2014	INFO	FailureEmail:   File "/share/MD0_DATA/.qpkg/Python/lib/python2.7/xmlrpclib.py", line 1224, in __call__
Fri Dec 12 22:30:54 2014	INFO	FailureEmail:     return self.__send(self.__name, args)
Fri Dec 12 22:30:54 2014	INFO	FailureEmail:   File "/share/MD0_DATA/.qpkg/Python/lib/python2.7/xmlrpclib.py", line 1570, in __request
Fri Dec 12 22:30:54 2014	INFO	FailureEmail:     verbose=self.__verbose
Fri Dec 12 22:30:54 2014	INFO	FailureEmail:   File "/share/MD0_DATA/.qpkg/Python/lib/python2.7/xmlrpclib.py", line 1264, in request
Fri Dec 12 22:30:54 2014	INFO	FailureEmail:     return self.single_request(host, handler, request_body, verbose)
Fri Dec 12 22:30:54 2014	INFO	FailureEmail:   File "/share/MD0_DATA/.qpkg/Python/lib/python2.7/xmlrpclib.py", line 1312, in single_request
Fri Dec 12 22:30:54 2014	INFO	FailureEmail:     response.msg,
Fri Dec 12 22:30:54 2014	INFO	FailureEmail: xmlrpclib.ProtocolError: <ProtocolError for nzbget:password@127.0.0.1:6789/xmlrpc: 401 Unauthorized>
Fri Dec 12 22:30:54 2014	ERROR	Post-process-script FailureEmail.py for VA-New In The SLAM!40 Week 49-2014 failed (terminated with unknown status)
I'm using nzbget 14.1 on my qnap. Normal email script works fine.

update: Seems username of nzbget was hardcoded to "nzbget" so after changing this it was working. But it seems it also sends mails on succes like the normal app does, so it doesn't work at all.

Post Reply

Who is online

Users browsing this forum: No registered users and 37 guests