NZBtoMedia Post-Processing issues in SAB (Mac OS)

Get help with all aspects of SABnzbd
Forum rules
Help us help you:
  • Are you using the latest stable version of SABnzbd? Downloads page.
  • Tell us what system you run SABnzbd on.
  • Adhere to the forum rules.
  • Do you experience problems during downloading?
    Check your connection in Status and Interface settings window.
    Use Test Server in Config > Servers.
    We will probably ask you to do a test using only basic settings.
  • Do you experience problems during repair or unpacking?
    Enable +Debug logging in the Status and Interface settings window and share the relevant parts of the log here using [ code ] sections.
Post Reply
XxUnkn0wnxX
Newbie
Newbie
Posts: 15
Joined: September 30th, 2015, 5:04 am

NZBtoMedia Post-Processing issues in SAB (Mac OS)

Post by XxUnkn0wnxX »

now this is in reference to this post here: https://github.com/clinton-hall/nzbToMe ... -144341962

now NZBtoMedia uses: #!/usr/bin/env python2

now for some reason only when SabNZB runs this script it tries to look for python in /usr/bin/python2 and this doesnt exist in Mac OS & never will

when i run any of the scripts manually i don't get this error: env: python2: No such file or directory

but when Sab runs it i get the error. and i haven't been able to determine why this only happens when Sab runs the script "nzbToSickBeard.py" which imports the nzbToMedia.py script

i need to resolve this as in Mac OS EL Capitan /usr/bin will be restricted and i won't be able to write to it meaning i will no longer be able to have this: sudo ln -s /usr/local/bin/python2 /usr/bin/python2 in place.

i have edited my /etc/paths file to have /usr/local/bin on top but as such SabNZB is still causing NZBtoMedia to ignore the /etc/paths file. why won't NZBtoMedia work? shouldn't #!/usr/bin/env python2 point to /usr/local/bin/python2 when Sab calls the script?

i am also running Sab From the Binary version not source on Mac & i noticed it has a prepackaged Python install in there so that must be messing with it, but still unsure how to resolve the issue at hand.
User avatar
shypike
Administrator
Administrator
Posts: 19773
Joined: January 18th, 2008, 12:49 pm

Re: NZBtoMedia Post-Processing issues in SAB (Mac OS)

Post by shypike »

How do you start SABnzbd?
Does it work when you start SABnzbd from a Terminal window
(like when you run the script manually)?
XxUnkn0wnxX
Newbie
Newbie
Posts: 15
Joined: September 30th, 2015, 5:04 am

Re: NZBtoMedia Post-Processing issues in SAB (Mac OS)

Post by XxUnkn0wnxX »

no i use the downloaded .app version of sabnzb so I'm not fully aware how the startup process is. if i where running it through source i would run it via terminal window or via Automator bash script.

well from sabnzb log i could gather this is how it starts when i run the .app:

2015-09-30 22:27:20,264::INFO::[SABnzbd:1688] 49632
2015-09-30 22:27:21,165::INFO::[SABnzbd:1255] Console logging for OSX App disabled
2015-09-30 22:27:21,165::INFO::[SABnzbd:1262] --------------------------------
2015-09-30 22:27:21,165::INFO::[SABnzbd:1263] SABnzbd.py-0.7.20 (rev=1df2943d05d64915a166e2c97e1eef86f72e3ff3)
2015-09-30 22:27:21,165::INFO::[SABnzbd:1275] Platform = posix
2015-09-30 22:27:21,166::INFO::[SABnzbd:1276] Python-version = 2.7.2 (default, Oct 11 2012, 20:14:37)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)]
2015-09-30 22:27:21,166::INFO::[SABnzbd:1277] Arguments = /Applications/SABnzbd.app/Contents/Resources/SABnzbd.py
User avatar
shypike
Administrator
Administrator
Posts: 19773
Joined: January 18th, 2008, 12:49 pm

Re: NZBtoMedia Post-Processing issues in SAB (Mac OS)

Post by shypike »

The thing is, when you run something from Terminal it gets its
environment variables from .bash_profile. The .app does not.
This may explain the difference.
One way to solve this is to find the place in nzbToSickBeard.py where it calls nzbToMedia.py
Put "python" before the script name and the first line of nzbToMedia.p will be ignored and the default
system Python will be used instead.
XxUnkn0wnxX
Newbie
Newbie
Posts: 15
Joined: September 30th, 2015, 5:04 am

Post by XxUnkn0wnxX »

well at the very top if nzbtoSIckbeard.py it has this #!/usr/bin/env python2

then the rest is hashed out till:

Code: Select all

### NZBGET POST-PROCESSING SCRIPT                                          ###
##############################################################################
import sys
import nzbToMedia

section = "SickBeard"
result = nzbToMedia.main(sys.argv, section)
sys.exit(result)
same with nzbtomedia.py it has #!/usr/bin/env python2

and then the script starts here:

Code: Select all

### NZBGET POST-PROCESSING SCRIPT                                          ###
##############################################################################
import os
import sys
import datetime
import core
from core.autoProcess.autoProcessComics import autoProcessComics
from core.autoProcess.autoProcessGames import autoProcessGames
from core.autoProcess.autoProcessMovie import autoProcessMovie
from core.autoProcess.autoProcessMusic import autoProcessMusic
from core.autoProcess.autoProcessTV import autoProcessTV
from core.nzbToMediaUtil import getDirs, extractFiles, cleanDir, update_downloadInfoStatus, get_downloadInfo, CharReplace, convert_to_ascii, get_nzoid, plex_update
from core.nzbToMediaUserScript import external_script
from core import logger, nzbToMediaDB

# post-processing
def process(inputDirectory, inputName=None, status=0, clientAgent='manual', download_id=None, inputCategory=None, failureLink=None):
    if core.SAFE_MODE and inputDirectory == core.NZB_DEFAULTDIR:
        logger.error(
            'The input directory:[%s] is the Default Download Directory. Please configure category directories to prevent processing of other media.' % (
            inputDirectory))
        return [-1, ""]

    if not download_id and clientAgent == 'sabnzbd':
        download_id = get_nzoid(inputName) 

    if clientAgent != 'manual' and not core.DOWNLOADINFO:
        logger.debug('Adding NZB download info for directory %s to database' % (inputDirectory))

        myDB = nzbToMediaDB.DBConnection()

        encoded, inputDirectory1 = CharReplace(inputDirectory)
        encoded, inputName1 = CharReplace(inputName)

        controlValueDict = {"input_directory": unicode(inputDirectory1)}
        newValueDict = {"input_name": unicode(inputName1),
                        "input_hash": unicode(download_id),
                        "input_id": unicode(download_id),
                        "client_agent": unicode(clientAgent),
                        "status": 0,
                        "last_update": datetime.date.today().toordinal()
        }
        myDB.upsert("downloads", newValueDict, controlValueDict)

    # auto-detect section
    if inputCategory is None:
        inputCategory = 'UNCAT'
    usercat = inputCategory
    section = core.CFG.findsection(inputCategory).isenabled()
    if section is None:
        section = core.CFG.findsection("ALL").isenabled()
        if section is None:
            logger.error(
                'Category:[%s] is not defined or is not enabled. Please rename it or ensure it is enabled for the appropriate section in your autoProcessMedia.cfg and try again.' % (
                inputCategory))
            return [-1, ""]
        else:
            usercat = "ALL"

    if len(section) > 1:
        logger.error(
            'Category:[%s] is not unique, %s are using it. Please rename it or disable all other sections using the same category name in your autoProcessMedia.cfg and try again.' % (
            inputCategory, section.keys()))
        return [-1, ""]

    if section:
        sectionName = section.keys()[0]
        logger.info('Auto-detected SECTION:%s' % (sectionName))
    else:
        logger.error("Unable to locate a section with subsection:%s enabled in your autoProcessMedia.cfg, exiting!" % (
            inputCategory))
        return [-1, ""]

    try:
        extract = int(section[usercat]['extract'])
    except:
        extract = 0

    try:
        if int(section[usercat]['remote_path']) and not core.REMOTEPATHS:
            logger.error('Remote Path is enabled for %s:%s but no Network mount points are defined. Please check your autoProcessMedia.cfg, exiting!' % (
                sectionName, inputCategory))
            return [-1, ""]
    except:
        logger.error('Remote Path %s is not valid for %s:%s Please set this to either 0 to disable or 1 to enable!' % (
            section[usercat]['remote_path'], sectionName, inputCategory))

    inputName, inputDirectory = convert_to_ascii(inputName, inputDirectory)

    if extract == 1:
        logger.debug('Checking for archives to extract in directory: %s' % (inputDirectory))
        extractFiles(inputDirectory)

    logger.info("Calling %s:%s to post-process:%s" % (sectionName, inputCategory, inputName))

    if sectionName == "CouchPotato":
        result = autoProcessMovie().process(sectionName, inputDirectory, inputName, status, clientAgent, download_id,
                                            inputCategory, failureLink)
    elif sectionName in ["SickBeard", "NzbDrone"]:
        result = autoProcessTV().processEpisode(sectionName, inputDirectory, inputName, status, clientAgent,
                                                download_id, inputCategory, failureLink)
    elif sectionName == "HeadPhones":
        result = autoProcessMusic().process(sectionName, inputDirectory, inputName, status, clientAgent, inputCategory)
    elif sectionName == "Mylar":
        result = autoProcessComics().processEpisode(sectionName, inputDirectory, inputName, status, clientAgent,
                                                    inputCategory)
    elif sectionName == "Gamez":
        result = autoProcessGames().process(sectionName, inputDirectory, inputName, status, clientAgent, inputCategory)
    elif sectionName == 'UserScript':
        result = external_script(inputDirectory, inputName, inputCategory, section[usercat])
    else:
        result = [-1, ""]

    plex_update(inputCategory)

    if result[0] == 0:
        if clientAgent != 'manual':
            # update download status in our DB
            update_downloadInfoStatus(inputName, 1)
        if not sectionName in ['UserScript', 'NzbDrone']:
            # cleanup our processing folders of any misc unwanted files and empty directories
            cleanDir(inputDirectory, sectionName, inputCategory)

    return result


def main(args, section=None):
    # Initialize the config
    core.initialize(section)

    # clientAgent for NZBs
    clientAgent = core.NZB_CLIENTAGENT

    logger.info("#########################################################")
    logger.info("## ..::[%s]::.. ##" % os.path.basename(__file__))
    logger.info("#########################################################")

    # debug command line options
    logger.debug("Options passed into nzbToMedia: %s" % args)

    # Post-Processing Result
    result = [0, ""]
    status = 0

    # NZBGet
    if os.environ.has_key('NZBOP_SCRIPTDIR'):
        # Check if the script is called from nzbget 11.0 or later
        if os.environ['NZBOP_VERSION'][0:5] < '11.0':
            logger.error("NZBGet Version %s is not supported. Please update NZBGet." %(str(os.environ['NZBOP_VERSION'])))
            sys.exit(core.NZBGET_POSTPROCESS_ERROR)

        logger.info("Script triggered from NZBGet Version %s." %(str(os.environ['NZBOP_VERSION'])))

        # Check if the script is called from nzbget 13.0 or later
        if os.environ.has_key('NZBPP_TOTALSTATUS'):
            if not os.environ['NZBPP_TOTALSTATUS'] == 'SUCCESS':
                logger.info("Download failed with status %s." %(os.environ['NZBPP_STATUS']))
                status = 1

        else:
            # Check par status
            if os.environ['NZBPP_PARSTATUS'] == '1' or os.environ['NZBPP_PARSTATUS'] == '4':
                logger.warning("Par-repair failed, setting status \"failed\"")
                status = 1

            # Check unpack status
            if os.environ['NZBPP_UNPACKSTATUS'] == '1':
                logger.warning("Unpack failed, setting status \"failed\"")
                status = 1

            if os.environ['NZBPP_UNPACKSTATUS'] == '0' and os.environ['NZBPP_PARSTATUS'] == '0':
                # Unpack was skipped due to nzb-file properties or due to errors during par-check

                if os.environ['NZBPP_HEALTH'] < 1000:
                    logger.warning(
                        "Download health is compromised and Par-check/repair disabled or no .par2 files found. Setting status \"failed\"")
                    logger.info("Please check your Par-check/repair settings for future downloads.")
                    status = 1

                else:
                    logger.info(
                        "Par-check/repair disabled or no .par2 files found, and Unpack not required. Health is ok so handle as though download successful")
                    logger.info("Please check your Par-check/repair settings for future downloads.")

        # Check for download_id to pass to CouchPotato
        download_id = ""
        failureLink = None
        if os.environ.has_key('NZBPR_COUCHPOTATO'):
            download_id = os.environ['NZBPR_COUCHPOTATO']
        elif os.environ.has_key('NZBPR_DRONE'):
            download_id = os.environ['NZBPR_DRONE']
        elif os.environ.has_key('NZBPR_SONARR'):
            download_id = os.environ['NZBPR_SONARR']
        if os.environ.has_key('NZBPR__DNZB_FAILURE'):
            failureLink = os.environ['NZBPR__DNZB_FAILURE']

        # All checks done, now launching the script.
        clientAgent = 'nzbget'
        result = process(os.environ['NZBPP_DIRECTORY'], inputName=os.environ['NZBPP_NZBNAME'], status=status,
                         clientAgent=clientAgent, download_id=download_id, inputCategory=os.environ['NZBPP_CATEGORY'],
                         failureLink=failureLink)
    # SABnzbd Pre 0.7.17
    elif len(args) == core.SABNZB_NO_OF_ARGUMENTS:
        # SABnzbd argv:
        # 1 The final directory of the job (full path)
        # 2 The original name of the NZB file
        # 3 Clean version of the job name (no path info and ".nzb" removed)
        # 4 Indexer's report number (if supported)
        # 5 User-defined category
        # 6 Group that the NZB was posted in e.g. alt.binaries.x
        # 7 Status of post processing. 0 = OK, 1=failed verification, 2=failed unpack, 3=1+2
        clientAgent = 'sabnzbd'
        logger.info("Script triggered from SABnzbd")
        result = process(args[1], inputName=args[2], status=args[7], inputCategory=args[5], clientAgent=clientAgent,
                         download_id='')
    # SABnzbd 0.7.17+
    elif len(args) >= core.SABNZB_0717_NO_OF_ARGUMENTS:
        # SABnzbd argv:
        # 1 The final directory of the job (full path)
        # 2 The original name of the NZB file
        # 3 Clean version of the job name (no path info and ".nzb" removed)
        # 4 Indexer's report number (if supported)
        # 5 User-defined category
        # 6 Group that the NZB was posted in e.g. alt.binaries.x
        # 7 Status of post processing. 0 = OK, 1=failed verification, 2=failed unpack, 3=1+2
        # 8 Failure URL
        clientAgent = 'sabnzbd'
        logger.info("Script triggered from SABnzbd 0.7.17+")
        result = process(args[1], inputName=args[2], status=args[7], inputCategory=args[5], clientAgent=clientAgent,
                        download_id='', failureLink=''.join(args[8:]))
    else:
        # Perform Manual Post-Processing
        logger.warning("Invalid number of arguments received from client, Switching to manual run mode ...")

        for section, subsections in core.SECTIONS.items():
            for subsection in subsections:
                if not core.CFG[section][subsection].isenabled():
                    continue
                for dirName in getDirs(section, subsection, link = 'move'):
                    logger.info("Starting manual run for %s:%s - Folder:%s" % (section, subsection, dirName))

                    logger.info("Checking database for download info for %s ..." % (os.path.basename(dirName)))
                    core.DOWNLOADINFO = get_downloadInfo(os.path.basename(dirName), 0)
                    if core.DOWNLOADINFO:
                        logger.info(
                            "Found download info for %s, setting variables now ..." % (os.path.basename(dirName)))
                    else:
                        logger.info(
                            'Unable to locate download info for %s, continuing to try and process this release ...' % (
                                os.path.basename(dirName))
                        )

                    try:
                        clientAgent = str(core.DOWNLOADINFO[0]['client_agent'])
                    except:
                        clientAgent = 'manual'
                    try:
                        download_id = str(core.DOWNLOADINFO[0]['input_id'])
                    except:
                        download_id = None

                    if clientAgent.lower() not in core.NZB_CLIENTS and clientAgent != 'manual':
                        continue

                    try:
                        dirName = dirName.encode(core.SYS_ENCODING)
                    except: pass
                    inputName = os.path.basename(dirName)
                    try:
                        inputName = inputName.encode(core.SYS_ENCODING)
                    except: pass

                    results = process(dirName, inputName, 0, clientAgent=clientAgent,
                                      download_id=download_id, inputCategory=subsection)
                    if results[0] != 0:
                        logger.error("A problem was reported when trying to perform a manual run for %s:%s." % (
                        section, subsection))
                        result = results

    if result[0] == 0:
        logger.info("The %s script completed successfully." % args[0])
        if result[1]:
            print result[1] + "!"  # For SABnzbd Status display.
        if os.environ.has_key('NZBOP_SCRIPTDIR'):  # return code for nzbget v11
            del core.MYAPP
            return (core.NZBGET_POSTPROCESS_SUCCESS)
    else:
        logger.error("A problem was reported in the %s script." % args[0])
        if result[1]:
            print result[1] + "!"  # For SABnzbd Status display.
        if os.environ.has_key('NZBOP_SCRIPTDIR'):  # return code for nzbget v11
            del core.MYAPP
            return (core.NZBGET_POSTPROCESS_ERROR)
    del core.MYAPP
    return (result[0])


if __name__ == '__main__':
    exit(main(sys.argv))
so i am a bit confused where to edit this...

i was hoping to find a solution without editing the script as it auto updates each time it is executed so any changes i make it would be wiped out...

is there no way for the .app to get the environmental variables from my .bash_profile or /etc/paths ?

if not would running sabnzb from source solve this issue?
User avatar
shypike
Administrator
Administrator
Posts: 19773
Joined: January 18th, 2008, 12:49 pm

Re: NZBtoMedia Post-Processing issues in SAB (Mac OS)

Post by shypike »

OK, replace the first line of both scripts with:
#!/usr/bin/python
XxUnkn0wnxX
Newbie
Newbie
Posts: 15
Joined: September 30th, 2015, 5:04 am

Re: NZBtoMedia Post-Processing issues in SAB (Mac OS)

Post by XxUnkn0wnxX »

k thx it worked but it a shame though why the author didn't do python2.7 or python in the first place as most systems have it.
but it will be frustrating that it will break each time the auto update changes the scripts back..

i was thinking if there was a way to write up another short script to load the nzbtosickbeard script

like a bash script that would do this for EG:

#!/usr/local/bin/bash
source ~/.bash_profile
python /Users/ADMIN/Apps/SickRage/contrib/nzbToMedia/nzbToSickBeard.py

this way the variables would be imported but i'm not sure how this would be done as when SAB runs the script it also includes the directory to post-process the items. if i run the script manually it won't know where to post-process the items..
User avatar
shypike
Administrator
Administrator
Posts: 19773
Joined: January 18th, 2008, 12:49 pm

Re: NZBtoMedia Post-Processing issues in SAB (Mac OS)

Post by shypike »

Code: Select all

#!/usr/local/bin/bash
source ~/.bash_profile
python /Users/ADMIN/Apps/SickRage/contrib/nzbToMedia/nzbToSickBeard.py $@
XxUnkn0wnxX
Newbie
Newbie
Posts: 15
Joined: September 30th, 2015, 5:04 am

Re: NZBtoMedia Post-Processing issues in SAB (Mac OS)

Post by XxUnkn0wnxX »

ok script ran but i got this error:

[03:58:45] [INFO]::MAIN: Loading config from [/Users/Admin/Apps/SickRage/contrib/nzbToMedia/autoProcessMedia.cfg]
[03:58:45] [INFO]::MAIN: Checking database structure...
[03:58:45] [INFO]::MAIN: Checking if git needs an update
[03:58:47] [INFO]::MAIN: No update needed
[03:58:47] [INFO]::MAIN: nzbToMedia Version:1cd64053b0da1d351bb6af392e1ebb904c6b6ce2 Branch:master (Darwin 14.5.0)
[03:58:47] [INFO]::MAIN: #########################################################
[03:58:47] [INFO]::MAIN: ## ..::[nzbToMedia.pyc]::.. ##
[03:58:47] [INFO]::MAIN: #########################################################
[03:58:47] [INFO]::MAIN: Script triggered from SABnzbd 0.7.17+
[03:58:47] [ERROR]::MAIN: Category:[Bad] is not defined or is not enabled. Please rename it or ensure it is enabled for the appropriate section in your autoProcessMedia.cfg and try again.

so how would i tell it what category to use? since i am calling out the script manly from my bash script
python /Users/ADMIN/Apps/SickRage/contrib/nzbToMedia/nzbToSickBeard.py $@

i asume $@ = the Directory location but would do i put at the end to include the category of that i have setup in Sab? or Manually set the category?
Last edited by XxUnkn0wnxX on October 3rd, 2015, 6:03 am, edited 1 time in total.
User avatar
shypike
Administrator
Administrator
Posts: 19773
Joined: January 18th, 2008, 12:49 pm

Re: NZBtoMedia Post-Processing issues in SAB (Mac OS)

Post by shypike »

$@ means: all parameters
Alternatively you can add:
$1 $2 $3 $4 $5 $6 $7 $8 $9
XxUnkn0wnxX
Newbie
Newbie
Posts: 15
Joined: September 30th, 2015, 5:04 am

Re: NZBtoMedia Post-Processing issues in SAB (Mac OS)

Post by XxUnkn0wnxX »

well i have tried setting different parameters at python /Users/ADMIN/Apps/SickRage/contrib/nzbToMedia/nzbToSickBeard.py $1 $5

but it still give me the category error. i don't much about the SabNZB scripting stuff

only basic unix scripts

i know that the
#!/usr/local/bin/bash
source ~/.bash_profile

resolves the path issues but when it get to the part running the actual post process script it fails as it is looking for both the SabNZB category argument and User download Directory argument. and that where I'm stuck.

because Sab obviously pipes in those arguments when it run the post process script. but since i am running it externally via a bash script i need to pipe in the arguments and I'm lost in that.
User avatar
shypike
Administrator
Administrator
Posts: 19773
Joined: January 18th, 2008, 12:49 pm

Re: NZBtoMedia Post-Processing issues in SAB (Mac OS)

Post by shypike »

Dis you read the nzbToMedia Wiki?
Especially https://github.com/clinton-hall/nzbToMedia/wiki/sabnzbd
XxUnkn0wnxX
Newbie
Newbie
Posts: 15
Joined: September 30th, 2015, 5:04 am

Re: NZBtoMedia Post-Processing issues in SAB (Mac OS)

Post by XxUnkn0wnxX »

i did read the wiki but it is no help as it only describes the settings to be set in SaB like here:

Image
Image

Usually when the script nzbToSickBeard.py runs it is run under normal conditions meaning when Sab Runs it, the script Detects the Download DIR & Category Set.

but since i wish to use my own simple bash script to run nzbToSickBeard.py so that the Paths are loaded properly. the script fails to fully work as it is being executed Via a bash script not via SabNZB directly therefore it fails to detect the Download DIR & Category that i have set.

so when my bash script runs i need it to mimic as if SabNZB where running it so it can see the Category that i have set & Download Dir of Sab.

i know this solution will resolve my Paths issues, like you said the .app doesnt read the User's set paths or /etc/paths file when a post processing script runs. but i do not know how to write it up in a way where both the paths get loaded up & nzbToSickBeard.py detects the Sab Arguments properly as would normally under normal conditions.

it would be much easier if in the actual script itself there was a argument or command to load the paths from ~/.bash_profile but i no nothing about python coding...
XxUnkn0wnxX
Newbie
Newbie
Posts: 15
Joined: September 30th, 2015, 5:04 am

Post by XxUnkn0wnxX »

ok thanks for all ur help i got it working :

ok after lots of trial and error i finally got it to work & without symtext errors:

#!/usr/local/bin/bash
source ~/.bash_profile
python ~/"Apps/SickRage/contrib/nzbToMedia/nzbToSickBeard.py" "$@"

it should work like this Apps/SickRage/contrib/nzbToMedia/nzbToSickBeard.py without the "" but the "" must be set for the $@ at the end.

~/ <-- points to your user home directory other wise copy the full path to where your script is.
EG
/Users/USER/Apps/SickRage/contrib/nzbToMedia/nzbToSickBeard.py

be sure there is no extra line in the bash script there should be only 3 lines of code.
User avatar
shypike
Administrator
Administrator
Posts: 19773
Joined: January 18th, 2008, 12:49 pm

Re: NZBtoMedia Post-Processing issues in SAB (Mac OS)

Post by shypike »

Interesting, I wouldn't have suspected that quotes were needed.
Nevertheless, good that it works now.
Post Reply