mirror of
https://github.com/nzbget/nzbget.git
synced 2026-04-19 20:36:52 -04:00
implemented general scripts concept which is an extension of the post-processing scripts concept initially introduced in v11; the general scripts concept applies to all scripts used in the program: scan-script, queue-script and scheduler-script (in addition to post-processing scripts); option "NzbProcess" renamed to "ScanScript"; option "NzbAddedProcess" renamed to "QueueScript"; option "DefScript" and "CategoryX.DefScript" renamed to "PostScript" and "CategoryX.PostScript" (options with old names are recognized and automatically converted on first settings saving); new option "TaskX.Script"; old option "TaskX.Process" kept for scheduling of external programs not related to nzbget (to avoid writing of intermediate proxy scripts); scan-script, queue-script and scheduler-script now work similar to post-processing scripts: -scripts must be put into scripts-directory; -scripts can be configured via web-interface and can have options; -multiple scripts can be chosen for each scripts-option, all chosen scripts are executed; -program and script options are passed to the script as env. variables;; renamed default directory with scripts from "ppscripts" to "scripts"; script signature indicates the type of script (post-processing, scan, queue or scheduler); one script can have mixed signature allowing it to be used for multiple purposes (for example a notification script can send a notification on both events: after adding to queue and after post-processing); result of RPC-method "configtemplates" has new fields "PostScript", "ScanScript", "QueueScript", "SchedulerScript" to indicate the purpose of the script; queue-script (formerly NzbAddedProcess) has new parameter "NZBNA_EVENT" indicating the reason of calling the script; currently the script is called only after adding of files to download queue and therefore the parameter is always set to "NZB_ADDED" but the queue-script can be called on other events in the future too
This commit is contained in:
@@ -42,15 +42,18 @@
|
||||
|
||||
#include "nzbget.h"
|
||||
#include "QueueScript.h"
|
||||
#include "Options.h"
|
||||
#include "Log.h"
|
||||
#include "Util.h"
|
||||
|
||||
extern Options* g_pOptions;
|
||||
|
||||
/**
|
||||
* If szStripPrefix is not NULL, only pp-parameters, whose names start with the prefix
|
||||
* are processed. The prefix is then stripped from the names.
|
||||
* If szStripPrefix is NULL, all pp-parameters are processed; without stripping.
|
||||
*/
|
||||
void QueueScriptController::PrepareEnvParameters(NZBParameterList* pParameters, const char* szStripPrefix)
|
||||
void NZBScriptController::PrepareEnvParameters(NZBParameterList* pParameters, const char* szStripPrefix)
|
||||
{
|
||||
int iPrefixLen = szStripPrefix ? strlen(szStripPrefix) : 0;
|
||||
|
||||
@@ -80,80 +83,150 @@ void QueueScriptController::PrepareEnvParameters(NZBParameterList* pParameters,
|
||||
}
|
||||
}
|
||||
|
||||
void NZBScriptController::PrepareEnvScript(NZBParameterList* pParameters, const char* szScriptName)
|
||||
{
|
||||
if (pParameters)
|
||||
{
|
||||
PrepareEnvParameters(pParameters, NULL);
|
||||
}
|
||||
|
||||
void NZBScriptController::ExecuteScript(const char* szScript, const char* szNZBFilename,
|
||||
char szParamPrefix[1024];
|
||||
snprintf(szParamPrefix, 1024, "%s:", szScriptName);
|
||||
szParamPrefix[1024-1] = '\0';
|
||||
|
||||
if (pParameters)
|
||||
{
|
||||
PrepareEnvParameters(pParameters, szParamPrefix);
|
||||
}
|
||||
|
||||
PrepareEnvOptions(szParamPrefix);
|
||||
}
|
||||
|
||||
void NZBScriptController::ExecuteScriptList(const char* szScriptList)
|
||||
{
|
||||
Options::ScriptList scriptList;
|
||||
g_pOptions->LoadScriptList(&scriptList);
|
||||
|
||||
for (Options::ScriptList::iterator it = scriptList.begin(); it != scriptList.end(); it++)
|
||||
{
|
||||
Options::Script* pScript = *it;
|
||||
|
||||
if (szScriptList && *szScriptList)
|
||||
{
|
||||
// split szScriptList into tokens
|
||||
char* szScriptList2 = strdup(szScriptList);
|
||||
char* saveptr;
|
||||
char* szScriptName = strtok_r(szScriptList2, ",;", &saveptr);
|
||||
while (szScriptName)
|
||||
{
|
||||
szScriptName = Util::Trim(szScriptName);
|
||||
if (*szScriptName && Util::SameFilename(szScriptName, pScript->GetName()))
|
||||
{
|
||||
ExecuteScript(pScript);
|
||||
break;
|
||||
}
|
||||
szScriptName = strtok_r(NULL, ",;", &saveptr);
|
||||
}
|
||||
free(szScriptList2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ScanScriptController::ExecuteScripts(const char* szNZBFilename,
|
||||
const char* szUrl, const char* szDirectory, char** pNZBName, char** pCategory,
|
||||
int* iPriority, NZBParameterList* pParameters, bool* bAddTop, bool* bAddPaused)
|
||||
{
|
||||
info("Executing nzb-process-script for %s", Util::BaseFileName(szNZBFilename));
|
||||
ScanScriptController* pScriptController = new ScanScriptController();
|
||||
|
||||
NZBScriptController* pScriptController = new NZBScriptController();
|
||||
pScriptController->SetScript(szScript);
|
||||
pScriptController->m_szNZBFilename = szNZBFilename;
|
||||
pScriptController->m_szUrl = szUrl;
|
||||
pScriptController->m_szDirectory = szDirectory;
|
||||
pScriptController->m_pNZBName = pNZBName;
|
||||
pScriptController->m_pCategory = pCategory;
|
||||
pScriptController->m_pParameters = pParameters;
|
||||
pScriptController->m_iPriority = iPriority;
|
||||
pScriptController->m_bAddTop = bAddTop;
|
||||
pScriptController->m_bAddPaused = bAddPaused;
|
||||
pScriptController->m_iPrefixLen = 0;
|
||||
|
||||
pScriptController->ExecuteScriptList(g_pOptions->GetScanScript());
|
||||
|
||||
delete pScriptController;
|
||||
}
|
||||
|
||||
void ScanScriptController::ExecuteScript(Options::Script* pScript)
|
||||
{
|
||||
if (!pScript->GetScanScript() || !Util::FileExists(m_szNZBFilename))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PrintMessage(Message::mkInfo, "Executing scan-script %s for %s", pScript->GetName(), Util::BaseFileName(m_szNZBFilename));
|
||||
|
||||
SetScript(pScript->GetLocation());
|
||||
SetArgs(NULL, false);
|
||||
|
||||
char szInfoName[1024];
|
||||
snprintf(szInfoName, 1024, "nzb-process-script for %s", Util::BaseFileName(szNZBFilename));
|
||||
snprintf(szInfoName, 1024, "scan-script %s for %s", pScript->GetName(), Util::BaseFileName(m_szNZBFilename));
|
||||
szInfoName[1024-1] = '\0';
|
||||
pScriptController->SetInfoName(szInfoName);
|
||||
SetInfoName(szInfoName);
|
||||
|
||||
pScriptController->SetEnvVar("NZBNP_FILENAME", szNZBFilename);
|
||||
pScriptController->SetEnvVar("NZBNP_URL", szUrl);
|
||||
pScriptController->SetEnvVar("NZBNP_NZBNAME", strlen(*pNZBName) > 0 ? *pNZBName : Util::BaseFileName(szNZBFilename));
|
||||
pScriptController->SetEnvVar("NZBNP_CATEGORY", *pCategory);
|
||||
pScriptController->SetIntEnvVar("NZBNP_PRIORITY", *iPriority);
|
||||
pScriptController->SetIntEnvVar("NZBNP_TOP", *bAddTop ? 1 : 0);
|
||||
pScriptController->SetIntEnvVar("NZBNP_PAUSED", *bAddPaused ? 1 : 0);
|
||||
SetLogPrefix(pScript->GetDisplayName());
|
||||
m_iPrefixLen = strlen(pScript->GetDisplayName()) + 2; // 2 = strlen(": ");
|
||||
PrepareParams(pScript->GetName());
|
||||
|
||||
Execute();
|
||||
|
||||
SetLogPrefix(NULL);
|
||||
}
|
||||
|
||||
void ScanScriptController::PrepareParams(const char* szScriptName)
|
||||
{
|
||||
ResetEnv();
|
||||
|
||||
SetEnvVar("NZBNP_FILENAME", m_szNZBFilename);
|
||||
SetEnvVar("NZBNP_URL", m_szUrl);
|
||||
SetEnvVar("NZBNP_NZBNAME", strlen(*m_pNZBName) > 0 ? *m_pNZBName : Util::BaseFileName(m_szNZBFilename));
|
||||
SetEnvVar("NZBNP_CATEGORY", *m_pCategory);
|
||||
SetIntEnvVar("NZBNP_PRIORITY", *m_iPriority);
|
||||
SetIntEnvVar("NZBNP_TOP", *m_bAddTop ? 1 : 0);
|
||||
SetIntEnvVar("NZBNP_PAUSED", *m_bAddPaused ? 1 : 0);
|
||||
|
||||
// remove trailing slash
|
||||
char szDir[1024];
|
||||
strncpy(szDir, szDirectory, 1024);
|
||||
strncpy(szDir, m_szDirectory, 1024);
|
||||
szDir[1024-1] = '\0';
|
||||
int iLen = strlen(szDir);
|
||||
if (szDir[iLen-1] == PATH_SEPARATOR)
|
||||
{
|
||||
szDir[iLen-1] = '\0';
|
||||
}
|
||||
pScriptController->SetEnvVar("NZBNP_DIRECTORY", szDir);
|
||||
SetEnvVar("NZBNP_DIRECTORY", szDir);
|
||||
|
||||
pScriptController->PrepareEnvParameters(pParameters, NULL);
|
||||
|
||||
char szLogPrefix[1024];
|
||||
strncpy(szLogPrefix, Util::BaseFileName(szScript), 1024);
|
||||
szLogPrefix[1024-1] = '\0';
|
||||
if (char* ext = strrchr(szLogPrefix, '.')) *ext = '\0'; // strip file extension
|
||||
pScriptController->SetLogPrefix(szLogPrefix);
|
||||
pScriptController->m_iPrefixLen = strlen(szLogPrefix) + 2; // 2 = strlen(": ");
|
||||
|
||||
pScriptController->Execute();
|
||||
|
||||
delete pScriptController;
|
||||
PrepareEnvScript(m_pParameters, szScriptName);
|
||||
}
|
||||
|
||||
void NZBScriptController::AddMessage(Message::EKind eKind, const char* szText)
|
||||
void ScanScriptController::AddMessage(Message::EKind eKind, const char* szText)
|
||||
{
|
||||
szText = szText + m_iPrefixLen;
|
||||
const char* szMsgText = szText + m_iPrefixLen;
|
||||
|
||||
if (!strncmp(szText, "[NZB] ", 6))
|
||||
if (!strncmp(szMsgText, "[NZB] ", 6))
|
||||
{
|
||||
debug("Command %s detected", szText + 6);
|
||||
if (!strncmp(szText + 6, "NZBNAME=", 8))
|
||||
debug("Command %s detected", szMsgText + 6);
|
||||
if (!strncmp(szMsgText + 6, "NZBNAME=", 8))
|
||||
{
|
||||
free(*m_pNZBName);
|
||||
*m_pNZBName = strdup(szText + 6 + 8);
|
||||
*m_pNZBName = strdup(szMsgText + 6 + 8);
|
||||
}
|
||||
else if (!strncmp(szText + 6, "CATEGORY=", 9))
|
||||
else if (!strncmp(szMsgText + 6, "CATEGORY=", 9))
|
||||
{
|
||||
free(*m_pCategory);
|
||||
*m_pCategory = strdup(szText + 6 + 9);
|
||||
*m_pCategory = strdup(szMsgText + 6 + 9);
|
||||
}
|
||||
else if (!strncmp(szText + 6, "NZBPR_", 6))
|
||||
else if (!strncmp(szMsgText + 6, "NZBPR_", 6))
|
||||
{
|
||||
char* szParam = strdup(szText + 6 + 6);
|
||||
char* szParam = strdup(szMsgText + 6 + 6);
|
||||
char* szValue = strchr(szParam, '=');
|
||||
if (szValue)
|
||||
{
|
||||
@@ -162,25 +235,25 @@ void NZBScriptController::AddMessage(Message::EKind eKind, const char* szText)
|
||||
}
|
||||
else
|
||||
{
|
||||
error("Invalid command \"%s\" received from %s", szText, GetInfoName());
|
||||
error("Invalid command \"%s\" received from %s", szMsgText, GetInfoName());
|
||||
}
|
||||
free(szParam);
|
||||
}
|
||||
else if (!strncmp(szText + 6, "PRIORITY=", 9))
|
||||
else if (!strncmp(szMsgText + 6, "PRIORITY=", 9))
|
||||
{
|
||||
*m_iPriority = atoi(szText + 6 + 9);
|
||||
*m_iPriority = atoi(szMsgText + 6 + 9);
|
||||
}
|
||||
else if (!strncmp(szText + 6, "TOP=", 4))
|
||||
else if (!strncmp(szMsgText + 6, "TOP=", 4))
|
||||
{
|
||||
*m_bAddTop = atoi(szText + 6 + 4) != 0;
|
||||
*m_bAddTop = atoi(szMsgText + 6 + 4) != 0;
|
||||
}
|
||||
else if (!strncmp(szText + 6, "PAUSED=", 7))
|
||||
else if (!strncmp(szMsgText + 6, "PAUSED=", 7))
|
||||
{
|
||||
*m_bAddPaused = atoi(szText + 6 + 7) != 0;
|
||||
*m_bAddPaused = atoi(szMsgText + 6 + 7) != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
error("Invalid command \"%s\" received from %s", szText, GetInfoName());
|
||||
error("Invalid command \"%s\" received from %s", szMsgText, GetInfoName());
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -190,44 +263,73 @@ void NZBScriptController::AddMessage(Message::EKind eKind, const char* szText)
|
||||
}
|
||||
|
||||
|
||||
void NZBAddedScriptController::StartScript(DownloadQueue* pDownloadQueue, NZBInfo *pNZBInfo, const char* szScript)
|
||||
QueueScriptController::~QueueScriptController()
|
||||
{
|
||||
NZBAddedScriptController* pScriptController = new NZBAddedScriptController();
|
||||
pScriptController->SetScript(szScript);
|
||||
pScriptController->m_szNZBName = strdup(pNZBInfo->GetName());
|
||||
pScriptController->SetEnvVar("NZBNA_NZBNAME", pNZBInfo->GetName());
|
||||
// "NZBNA_NAME" is not correct but kept for compatibility with older versions where this name was used by mistake
|
||||
pScriptController->SetEnvVar("NZBNA_NAME", pNZBInfo->GetName());
|
||||
pScriptController->SetIntEnvVar("NZBPP_NZBID", pNZBInfo->GetID());
|
||||
pScriptController->SetEnvVar("NZBNA_FILENAME", pNZBInfo->GetFilename());
|
||||
pScriptController->SetEnvVar("NZBNA_URL", pNZBInfo->GetURL());
|
||||
pScriptController->SetEnvVar("NZBNA_CATEGORY", pNZBInfo->GetCategory());
|
||||
pScriptController->SetIntEnvVar("NZBNA_LASTID", pNZBInfo->GetID());
|
||||
pScriptController->SetIntEnvVar("NZBNA_PRIORITY", pNZBInfo->GetPriority());
|
||||
free(m_szNZBName);
|
||||
free(m_szNZBFilename);
|
||||
free(m_szUrl);
|
||||
free(m_szCategory);
|
||||
}
|
||||
|
||||
pScriptController->PrepareEnvParameters(pNZBInfo->GetParameters(), NULL);
|
||||
void QueueScriptController::StartScripts(DownloadQueue* pDownloadQueue, NZBInfo *pNZBInfo)
|
||||
{
|
||||
QueueScriptController* pScriptController = new QueueScriptController();
|
||||
|
||||
pScriptController->m_szNZBName = strdup(pNZBInfo->GetName());
|
||||
pScriptController->m_szNZBFilename = strdup(pNZBInfo->GetFilename());
|
||||
pScriptController->m_szUrl = strdup(pNZBInfo->GetURL());
|
||||
pScriptController->m_szCategory = strdup(pNZBInfo->GetCategory());
|
||||
pScriptController->m_iID = pNZBInfo->GetID();
|
||||
pScriptController->m_iPriority = pNZBInfo->GetPriority();
|
||||
pScriptController->m_Parameters.CopyFrom(pNZBInfo->GetParameters());
|
||||
|
||||
pScriptController->SetAutoDestroy(true);
|
||||
|
||||
pScriptController->Start();
|
||||
}
|
||||
|
||||
void NZBAddedScriptController::Run()
|
||||
void QueueScriptController::Run()
|
||||
{
|
||||
ExecuteScriptList(g_pOptions->GetQueueScript());
|
||||
}
|
||||
|
||||
void QueueScriptController::ExecuteScript(Options::Script* pScript)
|
||||
{
|
||||
if (!pScript->GetQueueScript())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PrintMessage(Message::mkInfo, "Executing queue-script %s for %s", pScript->GetName(), Util::BaseFileName(m_szNZBName));
|
||||
|
||||
SetScript(pScript->GetLocation());
|
||||
SetArgs(NULL, false);
|
||||
|
||||
char szInfoName[1024];
|
||||
snprintf(szInfoName, 1024, "nzb-added process-script for %s", m_szNZBName);
|
||||
snprintf(szInfoName, 1024, "queue-script %s for %s", pScript->GetName(), Util::BaseFileName(m_szNZBName));
|
||||
szInfoName[1024-1] = '\0';
|
||||
SetInfoName(szInfoName);
|
||||
|
||||
info("Executing %s", szInfoName);
|
||||
|
||||
char szLogPrefix[1024];
|
||||
strncpy(szLogPrefix, Util::BaseFileName(GetScript()), 1024);
|
||||
szLogPrefix[1024-1] = '\0';
|
||||
if (char* ext = strrchr(szLogPrefix, '.')) *ext = '\0'; // strip file extension
|
||||
SetLogPrefix(szLogPrefix);
|
||||
SetLogPrefix(pScript->GetDisplayName());
|
||||
PrepareParams(pScript->GetName());
|
||||
|
||||
Execute();
|
||||
|
||||
free(m_szNZBName);
|
||||
SetLogPrefix(NULL);
|
||||
}
|
||||
|
||||
void QueueScriptController::PrepareParams(const char* szScriptName)
|
||||
{
|
||||
ResetEnv();
|
||||
|
||||
SetEnvVar("NZBNA_NZBNAME", m_szNZBName);
|
||||
SetIntEnvVar("NZBNA_NZBID", m_iID);
|
||||
SetEnvVar("NZBNA_FILENAME", m_szNZBFilename);
|
||||
SetEnvVar("NZBNA_URL", m_szUrl);
|
||||
SetEnvVar("NZBNA_EVENT", "NZB_ADDED");
|
||||
SetEnvVar("NZBNA_CATEGORY", m_szCategory);
|
||||
SetIntEnvVar("NZBNA_PRIORITY", m_iPriority);
|
||||
SetIntEnvVar("NZBNA_LASTID", m_iID); // deprecated
|
||||
|
||||
PrepareEnvScript(&m_Parameters, szScriptName);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user