From 2fcfbc2e1a06f1c7ca7798c9505cb9ac55b3cb61 Mon Sep 17 00:00:00 2001 From: Andrey Prygunkov Date: Fri, 16 Nov 2012 20:50:56 +0000 Subject: [PATCH] added new option to setup a script called after a nzb-file is added to queue --- Options.cpp | 8 +++++ Options.h | 2 ++ PrePostProcessor.cpp | 5 ++++ ScriptController.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++ ScriptController.h | 10 +++++++ nzbget.conf | 47 +++++++++++++++++++++++++++++- 6 files changed, 140 insertions(+), 1 deletion(-) diff --git a/Options.cpp b/Options.cpp index 71933d45..d2273955 100644 --- a/Options.cpp +++ b/Options.cpp @@ -139,6 +139,7 @@ static const char* OPTION_PARREPAIR = "ParRepair"; static const char* OPTION_POSTPROCESS = "PostProcess"; static const char* OPTION_POSTCONFIGFILE = "PostConfigFile"; static const char* OPTION_NZBPROCESS = "NZBProcess"; +static const char* OPTION_NZBADDEDPROCESS = "NZBAddedProcess"; static const char* OPTION_STRICTPARNAME = "StrictParName"; static const char* OPTION_UMASK = "UMask"; static const char* OPTION_UPDATEINTERVAL = "UpdateInterval"; @@ -342,6 +343,7 @@ Options::Options(int argc, char* argv[]) m_szPostProcess = NULL; m_szPostConfigFilename = NULL; m_szNZBProcess = NULL; + m_szNZBAddedProcess = NULL; m_bStrictParName = false; m_bNoConfig = false; m_iUMask = 0; @@ -523,6 +525,10 @@ Options::~Options() { free(m_szNZBProcess); } + if (m_szNZBAddedProcess) + { + free(m_szNZBAddedProcess); + } if (m_pEditQueueIDList) { free(m_pEditQueueIDList); @@ -613,6 +619,7 @@ void Options::InitDefault() SetOption(OPTION_POSTPROCESS, ""); SetOption(OPTION_POSTCONFIGFILE, ""); SetOption(OPTION_NZBPROCESS, ""); + SetOption(OPTION_NZBADDEDPROCESS, ""); SetOption(OPTION_STRICTPARNAME, "yes"); SetOption(OPTION_DAEMONUSERNAME, "root"); SetOption(OPTION_UMASK, "1000"); @@ -759,6 +766,7 @@ void Options::InitOptions() m_szPostProcess = strdup(GetOption(OPTION_POSTPROCESS)); m_szNZBProcess = strdup(GetOption(OPTION_NZBPROCESS)); + m_szNZBAddedProcess = strdup(GetOption(OPTION_NZBADDEDPROCESS)); m_szControlIP = strdup(GetOption(OPTION_CONTROLIP)); m_szControlPassword = strdup(GetOption(OPTION_CONTROLPASSWORD)); m_szLockFile = strdup(GetOption(OPTION_LOCKFILE)); diff --git a/Options.h b/Options.h index 96296bba..7d7fcd26 100644 --- a/Options.h +++ b/Options.h @@ -191,6 +191,7 @@ private: char* m_szPostProcess; char* m_szPostConfigFilename; char* m_szNZBProcess; + char* m_szNZBAddedProcess; bool m_bStrictParName; bool m_bNoConfig; int m_iUMask; @@ -333,6 +334,7 @@ public: const char* GetPostProcess() { return m_szPostProcess; } const char* GetPostConfigFilename() { return m_szPostConfigFilename; } const char* GetNZBProcess() { return m_szNZBProcess; } + const char* GetNZBAddedProcess() { return m_szNZBAddedProcess; } bool GetStrictParName() { return m_bStrictParName; } int GetUMask() { return m_iUMask; } int GetUpdateInterval() {return m_iUpdateInterval; } diff --git a/PrePostProcessor.cpp b/PrePostProcessor.cpp index a2c6bc53..e193dd13 100644 --- a/PrePostProcessor.cpp +++ b/PrePostProcessor.cpp @@ -270,6 +270,11 @@ void PrePostProcessor::NZBAdded(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo { PausePars(pDownloadQueue, pNZBInfo); } + + if (strlen(g_pOptions->GetNZBAddedProcess()) > 0) + { + NZBAddedScriptController::StartScript(pDownloadQueue, pNZBInfo, g_pOptions->GetNZBAddedProcess()); + } } void PrePostProcessor::NZBDownloaded(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo) diff --git a/ScriptController.cpp b/ScriptController.cpp index 7646a02a..47a0fe8c 100644 --- a/ScriptController.cpp +++ b/ScriptController.cpp @@ -894,6 +894,75 @@ void NZBScriptController::AddMessage(Message::EKind eKind, bool bDefaultKind, Op } } +void NZBAddedScriptController::StartScript(DownloadQueue* pDownloadQueue, NZBInfo *pNZBInfo, const char* szScript) +{ + NZBAddedScriptController* pScriptController = new NZBAddedScriptController(); + pScriptController->SetScript(szScript); + pScriptController->m_szNZBName = strdup(pNZBInfo->GetName()); + pScriptController->SetEnvVar("NZBNA_NAME", pNZBInfo->GetName()); + pScriptController->SetEnvVar("NZBNA_FILENAME", pNZBInfo->GetFilename()); + pScriptController->SetEnvVar("NZBNA_CATEGORY", pNZBInfo->GetCategory()); + + int iLastID = 0; + int iMaxPriority = 0; + + for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++) + { + FileInfo* pFileInfo = *it; + if (pFileInfo->GetNZBInfo() == pNZBInfo && ( pFileInfo->GetPriority() > iMaxPriority || iLastID == 0)) + { + iMaxPriority = pFileInfo->GetPriority(); + } + if (pFileInfo->GetNZBInfo() == pNZBInfo && pFileInfo->GetID() > iLastID) + { + iLastID = pFileInfo->GetID(); + } + } + + char buf[100]; + + snprintf(buf, 100, "%i", iLastID); + pScriptController->SetEnvVar("NZBNA_LASTID", buf); + + snprintf(buf, 100, "%i", iMaxPriority); + pScriptController->SetEnvVar("NZBNA_PRIORITY", buf); + + for (NZBParameterList::iterator it = pNZBInfo->GetParameters()->begin(); it != pNZBInfo->GetParameters()->end(); it++) + { + NZBParameter* pParameter = *it; + char szVarname[1024]; + snprintf(szVarname, sizeof(szVarname), "NZBPR_%s", pParameter->GetName()); + szVarname[1024-1] = '\0'; + pScriptController->SetEnvVar(szVarname, pParameter->GetValue()); + } + + pScriptController->SetAutoDestroy(true); + + pScriptController->Start(); +} + +void NZBAddedScriptController::Run() +{ + char szInfoName[1024]; + snprintf(szInfoName, 1024, "nzb-added process-script for %s", m_szNZBName); + szInfoName[1024-1] = '\0'; + SetInfoName(szInfoName); + + info("Executing %s", szInfoName); + + SetDefaultKindPrefix("NZB-Added Process: "); + SetDefaultLogKind(g_pOptions->GetProcessLogKind()); + + const char* szArgs[2]; + szArgs[0] = GetScript(); + szArgs[1] = NULL; + SetArgs(szArgs, false); + + Execute(); + + free(m_szNZBName); +} + void SchedulerScriptController::StartScript(const char* szCommandLine) { char** argv = NULL; diff --git a/ScriptController.h b/ScriptController.h index fb6a3aab..9ee505af 100644 --- a/ScriptController.h +++ b/ScriptController.h @@ -124,6 +124,16 @@ public: static void ExecuteScript(const char* szScript, const char* szNZBFilename, const char* szDirectory, char** pCategory, int* iPriority, NZBParameterList* pParameterList); }; +class NZBAddedScriptController : public Thread, ScriptController +{ +private: + char* m_szNZBName; + +public: + virtual void Run(); + static void StartScript(DownloadQueue* pDownloadQueue, NZBInfo *pNZBInfo, const char* szScript); +}; + class SchedulerScriptController : public Thread, ScriptController { public: diff --git a/nzbget.conf b/nzbget.conf index 0e49b430..a9427665 100644 --- a/nzbget.conf +++ b/nzbget.conf @@ -244,7 +244,7 @@ MergeNzb=no # NZBNP_FILENAME - name of file to be processed; # # In addition to these arguments NZBGet passes all -# nzbget.conf-options to postprocess-program as environment variables. These +# nzbget.conf-options to nzbprocess-program as environment variables. These # variables have prefix "NZBOP_" and are written in UPPER CASE. For Example # option "ParRepair" is passed as environment variable "NZBOP_PARREPAIR". # The dots in option names are replaced with underscores, for example @@ -287,6 +287,51 @@ MergeNzb=no # archives, if they were already processed by the script. NzbProcess= +# Set path to program, that must be executed after a nzb-file is added +# to queue. +# +# This program is called each time a new nzb-file is added to queue: from +# nzb incoming directory, via command line call "nzbget -A filename.nzb", +# via RPC-method "append" or from web-interface. +# +# Example: "NzbAddedProcess=~/nzbaddedprocess.sh". +# +# That program can modify the files in download queue (for example +# delete or pause all nfo, sfv, sample files) or do something else. +# +# INFO FOR DEVELOPERS: +# NZBGet passes following arguments to nzbaddedprocess-program as environment +# variables: +# NZBNA_NZBNAME - name of nzb-group. This name can be used in calls +# to nzbget edit-command using subswitch "-GN name"; +# NZBNA_FILENAME - filename of the nzb-file. If the file was added +# from nzb-directory this is the fullname with path. +# If the file was added via web-interface it contains +# only filename without path; +# NZBNA_CATEGORY - category of nzb-file (if assigned); +# NZBNA_LASTID - the id of the last file in the nzb-file. This ID can +# be used with calls to nzbget edit-command; +# NZBNA_PRIORITY - priority (default is 0). +# +# In addition to these arguments NZBGet passes all +# nzbget.conf-options to nzbaddedprocess-program as environment variables. These +# variables have prefix "NZBOP_" and are written in UPPER CASE. For Example +# option "ParRepair" is passed as environment variable "NZBOP_PARREPAIR". +# The dots in option names are replaced with underscores, for example +# "SERVER1_HOST". For options with predefined possible values (yes/no, etc.) +# the values are passed always in lower case. +# +# Examples: +# 1) pausing nzb-file using file-id: +# "$NZBOP_APPBIN" -c "$NZBOP_CONFIGFILE" -E G P $NZBNA_LASTID +# +# 2) setting category using nzb-name: +# "$NZBOP_APPBIN" -c "$NZBOP_CONFIGFILE" -E GN K "my cat" "$NZBNA_NZBNAME" +# +# 3) pausing files with extension "nzb": +# "$NZBOP_APPBIN" -c "$NZBOP_CONFIGFILE" -E FR P "$NZBNA_NAME/.*\.nzb" +NzbAddedProcess= + # Check for duplicate files (yes, no). # # If this option is enabled the program checks by adding of a new nzb-file: