mirror of
https://github.com/nzbget/nzbget.git
synced 2026-02-19 07:13:57 -05:00
added built-in unpack: 1) rar and 7-zip formats are supported (via external Unrar and 7-Zip executables); 2) new options <Unpack>, <UnpackPauseQueue>, <UnpackCleanupDisk>, <UnrarCmd>, <SevenZipCmd>; 3) web-interface now shows progress and estimated time during unpack (rar only; for 7-Zip progress is not available due to limitations of 7-Zip) 4) when built-in unpack is enabled, the post-processing script is called after unpack and possibly par-check/repair (if needed); 5) for nzb-files containing multiple collections (par-sets) the post-processing script is called only once, after the last par-set; 6) new parameter <NZBPP_UNPACKSTATUS> passed to post-processing script; 7) if the option <AllowReProcess> is enabled the post-processing-script is called after each par-set (as in previous versions); 8) example post-processing script updated: removed unrar-code, added check for unpack status; 9) new field <UnpackStatus> in result of RPC-method <history>; 10) history-dialog in web-interface shows three status: par-status, unpack-status, script-status; 11) with two built-in special post-processing parameters <*Unpack:> and <*Unpack:Password> the unpack can be disabled for individual nzb-file or the password can be set; 12) built-in special post-processing parameters can be set via web-interface on page <PP-Parameters> (when built-in unpack is enabled).
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of nzbget
|
||||
*
|
||||
* Copyright (C) 2007-2011 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
* Copyright (C) 2007-2013 Andrey Prygunkov <hugbug@users.sourceforge.net>
|
||||
*
|
||||
* 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
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "nzbget.h"
|
||||
#include "ScriptController.h"
|
||||
@@ -243,12 +244,6 @@ void ScriptController::PrepareEnvironmentStrings()
|
||||
|
||||
int ScriptController::Execute()
|
||||
{
|
||||
if (!Util::FileExists(m_szScript))
|
||||
{
|
||||
error("Could not start %s: could not find file %s", m_szInfoName, m_szScript);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PrepareEnvironmentStrings();
|
||||
|
||||
int iExitCode = 0;
|
||||
@@ -299,8 +294,7 @@ int ScriptController::Execute()
|
||||
DWORD dwErrCode = GetLastError();
|
||||
char szErrMsg[255];
|
||||
szErrMsg[255-1] = '\0';
|
||||
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM || FORMAT_MESSAGE_IGNORE_INSERTS || FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
||||
NULL, dwErrCode, 0, szErrMsg, 255, NULL))
|
||||
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErrCode, 0, szErrMsg, 255, NULL))
|
||||
{
|
||||
error("Could not start %s: %s", m_szInfoName, szErrMsg);
|
||||
}
|
||||
@@ -308,6 +302,10 @@ int ScriptController::Execute()
|
||||
{
|
||||
error("Could not start %s: error %i", m_szInfoName, dwErrCode);
|
||||
}
|
||||
if (!Util::FileExists(m_szScript))
|
||||
{
|
||||
error("Could not find file %s", m_szScript);
|
||||
}
|
||||
free(szEnvironmentStrings);
|
||||
return -1;
|
||||
}
|
||||
@@ -370,6 +368,7 @@ int ScriptController::Execute()
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
chdir(m_szWorkingDir);
|
||||
execve(m_szScript, (char* const*)m_szArgs, (char* const*)pEnvironmentStrings);
|
||||
fprintf(stdout, "[ERROR] Could not start script: %s", strerror(errno));
|
||||
fflush(stdout);
|
||||
@@ -409,7 +408,7 @@ int ScriptController::Execute()
|
||||
debug("Entering pipe-loop");
|
||||
while (!feof(readpipe) && !m_bTerminated)
|
||||
{
|
||||
if (fgets(buf, 10240, readpipe))
|
||||
if (ReadLine(buf, 10240, readpipe))
|
||||
{
|
||||
#ifdef CHILD_WATCHDOG
|
||||
if (!bChildConfirmed)
|
||||
@@ -503,6 +502,11 @@ void ScriptController::Terminate()
|
||||
debug("Stopped %s", m_szInfoName);
|
||||
}
|
||||
|
||||
bool ScriptController::ReadLine(char* szBuf, int iBufSize, FILE* pStream)
|
||||
{
|
||||
return fgets(szBuf, iBufSize, pStream);
|
||||
}
|
||||
|
||||
void ScriptController::ProcessOutput(char* szText)
|
||||
{
|
||||
debug("Processing output received from script");
|
||||
@@ -517,23 +521,23 @@ void ScriptController::ProcessOutput(char* szText)
|
||||
|
||||
if (!strncmp(szText, "[INFO] ", 7))
|
||||
{
|
||||
AddMessage(Message::mkInfo, false, g_pOptions->GetInfoTarget(), szText + 7);
|
||||
AddMessage(Message::mkInfo, false, szText + 7);
|
||||
}
|
||||
else if (!strncmp(szText, "[WARNING] ", 10))
|
||||
{
|
||||
AddMessage(Message::mkWarning, false, g_pOptions->GetWarningTarget(), szText + 10);
|
||||
AddMessage(Message::mkWarning, false, szText + 10);
|
||||
}
|
||||
else if (!strncmp(szText, "[ERROR] ", 8))
|
||||
{
|
||||
AddMessage(Message::mkError, false, g_pOptions->GetErrorTarget(), szText + 8);
|
||||
AddMessage(Message::mkError, false, szText + 8);
|
||||
}
|
||||
else if (!strncmp(szText, "[DETAIL] ", 9))
|
||||
{
|
||||
AddMessage(Message::mkDetail, false, g_pOptions->GetDetailTarget(), szText + 9);
|
||||
AddMessage(Message::mkDetail, false, szText + 9);
|
||||
}
|
||||
else if (!strncmp(szText, "[DEBUG] ", 8))
|
||||
{
|
||||
AddMessage(Message::mkDebug, false, g_pOptions->GetDebugTarget(), szText + 8);
|
||||
AddMessage(Message::mkDebug, false, szText + 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -543,23 +547,23 @@ void ScriptController::ProcessOutput(char* szText)
|
||||
break;
|
||||
|
||||
case Options::slDetail:
|
||||
AddMessage(Message::mkDetail, true, g_pOptions->GetDetailTarget(), szText);
|
||||
AddMessage(Message::mkDetail, true, szText);
|
||||
break;
|
||||
|
||||
case Options::slInfo:
|
||||
AddMessage(Message::mkInfo, true, g_pOptions->GetInfoTarget(), szText);
|
||||
AddMessage(Message::mkInfo, true, szText);
|
||||
break;
|
||||
|
||||
case Options::slWarning:
|
||||
AddMessage(Message::mkWarning, true, g_pOptions->GetWarningTarget(), szText);
|
||||
AddMessage(Message::mkWarning, true, szText);
|
||||
break;
|
||||
|
||||
case Options::slError:
|
||||
AddMessage(Message::mkError, true, g_pOptions->GetErrorTarget(), szText);
|
||||
AddMessage(Message::mkError, true, szText);
|
||||
break;
|
||||
|
||||
case Options::slDebug:
|
||||
AddMessage(Message::mkDebug, true, g_pOptions->GetDebugTarget(), szText);
|
||||
AddMessage(Message::mkDebug, true, szText);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -567,7 +571,7 @@ void ScriptController::ProcessOutput(char* szText)
|
||||
debug("Processing output received from script - completed");
|
||||
}
|
||||
|
||||
void ScriptController::AddMessage(Message::EKind eKind, bool bDefaultKind, Options::EMessageTarget eMessageTarget, const char* szText)
|
||||
void ScriptController::AddMessage(Message::EKind eKind, bool bDefaultKind, const char* szText)
|
||||
{
|
||||
switch (eKind)
|
||||
{
|
||||
@@ -593,13 +597,26 @@ void ScriptController::AddMessage(Message::EKind eKind, bool bDefaultKind, Optio
|
||||
}
|
||||
}
|
||||
|
||||
void PostScriptController::StartScriptJob(PostInfo* pPostInfo, const char* szScript, bool bNZBFileCompleted, bool bHasFailedParJobs)
|
||||
void ScriptController::PrintMessage(Message::EKind eKind, const char* szFormat, ...)
|
||||
{
|
||||
char tmp2[1024];
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, szFormat);
|
||||
vsnprintf(tmp2, 1024, szFormat, ap);
|
||||
tmp2[1024-1] = '\0';
|
||||
va_end(ap);
|
||||
|
||||
AddMessage(eKind, false, tmp2);
|
||||
}
|
||||
|
||||
void PostScriptController::StartScriptJob(PostInfo* pPostInfo, bool bNZBFileCompleted, bool bHasFailedParJobs)
|
||||
{
|
||||
info("Executing post-process-script for %s", pPostInfo->GetInfoName());
|
||||
|
||||
PostScriptController* pScriptController = new PostScriptController();
|
||||
pScriptController->m_pPostInfo = pPostInfo;
|
||||
pScriptController->SetScript(szScript);
|
||||
pScriptController->SetScript(g_pOptions->GetPostProcess());
|
||||
pScriptController->SetWorkingDir(g_pOptions->GetDestDir());
|
||||
pScriptController->m_bNZBFileCompleted = bNZBFileCompleted;
|
||||
pScriptController->m_bHasFailedParJobs = bHasFailedParJobs;
|
||||
@@ -620,9 +637,14 @@ void PostScriptController::Run()
|
||||
szNZBName[1024-1] = '\0';
|
||||
|
||||
char szParStatus[10];
|
||||
snprintf(szParStatus, 10, "%i", m_pPostInfo->GetParStatus());
|
||||
snprintf(szParStatus, 10, "%i", g_pOptions->GetAllowReProcess() ? (int)m_pPostInfo->GetParStatus() : (int)m_pPostInfo->GetNZBInfo()->GetParStatus());
|
||||
szParStatus[10-1] = '\0';
|
||||
|
||||
int iUnpackStatus[] = { 0, 0, 1, 2 };
|
||||
char szUnpackStatus[10];
|
||||
snprintf(szUnpackStatus, 10, "%i", g_pOptions->GetAllowReProcess() ? 0 : iUnpackStatus[m_pPostInfo->GetNZBInfo()->GetUnpackStatus()]);
|
||||
szUnpackStatus[10-1] = '\0';
|
||||
|
||||
char szCollectionCompleted[10];
|
||||
snprintf(szCollectionCompleted, 10, "%i", (int)m_bNZBFileCompleted);
|
||||
szCollectionCompleted[10-1] = '\0';
|
||||
@@ -648,7 +670,7 @@ void PostScriptController::Run()
|
||||
szCategory[1024-1] = '\0';
|
||||
|
||||
char szInfoName[1024];
|
||||
snprintf(szInfoName, 1024, "post-process-script for %s", m_pPostInfo->GetInfoName());
|
||||
snprintf(szInfoName, 1024, "post-process-script for %s", g_pOptions->GetAllowReProcess() ? m_pPostInfo->GetInfoName() : m_pPostInfo->GetNZBInfo()->GetName());
|
||||
szInfoName[1024-1] = '\0';
|
||||
SetInfoName(szInfoName);
|
||||
|
||||
@@ -672,6 +694,7 @@ void PostScriptController::Run()
|
||||
SetEnvVar("NZBPP_NZBFILENAME", szNZBFilename);
|
||||
SetEnvVar("NZBPP_PARFILENAME", szParFilename);
|
||||
SetEnvVar("NZBPP_PARSTATUS", szParStatus);
|
||||
SetEnvVar("NZBPP_UNPACKSTATUS", szUnpackStatus);
|
||||
SetEnvVar("NZBPP_NZBCOMPLETED", szCollectionCompleted);
|
||||
SetEnvVar("NZBPP_PARFAILED", szHasFailedParJobs);
|
||||
SetEnvVar("NZBPP_CATEGORY", szCategory);
|
||||
@@ -689,14 +712,17 @@ void PostScriptController::Run()
|
||||
|
||||
int iResult = Execute();
|
||||
|
||||
szInfoName[0] = 'P'; // uppercase
|
||||
|
||||
switch (iResult)
|
||||
{
|
||||
case POSTPROCESS_SUCCESS:
|
||||
info("%s sucessful", szInfoName);
|
||||
info("%s successful", szInfoName);
|
||||
m_pPostInfo->SetScriptStatus(PostInfo::srSuccess);
|
||||
break;
|
||||
|
||||
case POSTPROCESS_ERROR:
|
||||
case -1: // Execute() returns -1 if the process could not be started (file not found or other problem)
|
||||
info("%s failed", szInfoName);
|
||||
m_pPostInfo->SetScriptStatus(PostInfo::srFailure);
|
||||
break;
|
||||
@@ -755,26 +781,18 @@ void PostScriptController::Run()
|
||||
m_pPostInfo->SetWorking(false);
|
||||
}
|
||||
|
||||
void PostScriptController::AddMessage(Message::EKind eKind, bool bDefaultKind, Options::EMessageTarget eMessageTarget, const char* szText)
|
||||
void PostScriptController::AddMessage(Message::EKind eKind, bool bDefaultKind, const char* szText)
|
||||
{
|
||||
if (!strncmp(szText, "[HISTORY] ", 10))
|
||||
{
|
||||
if (eMessageTarget == Options::mtScreen || eMessageTarget == Options::mtBoth)
|
||||
{
|
||||
m_pPostInfo->GetNZBInfo()->AppendMessage(eKind, 0, szText + 10);
|
||||
}
|
||||
m_pPostInfo->GetNZBInfo()->AppendMessage(eKind, 0, szText + 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScriptController::AddMessage(eKind, bDefaultKind, eMessageTarget, szText);
|
||||
|
||||
if (eMessageTarget == Options::mtScreen || eMessageTarget == Options::mtBoth)
|
||||
{
|
||||
m_pPostInfo->AppendMessage(eKind, szText);
|
||||
}
|
||||
ScriptController::AddMessage(eKind, bDefaultKind, szText);
|
||||
m_pPostInfo->AppendMessage(eKind, szText);
|
||||
}
|
||||
|
||||
|
||||
if (g_pOptions->GetPausePostProcess())
|
||||
{
|
||||
time_t tStageTime = m_pPostInfo->GetStageTime();
|
||||
@@ -854,7 +872,7 @@ void NZBScriptController::ExecuteScript(const char* szScript, const char* szNZBF
|
||||
delete pScriptController;
|
||||
}
|
||||
|
||||
void NZBScriptController::AddMessage(Message::EKind eKind, bool bDefaultKind, Options::EMessageTarget eMessageTarget, const char* szText)
|
||||
void NZBScriptController::AddMessage(Message::EKind eKind, bool bDefaultKind, const char* szText)
|
||||
{
|
||||
if (!strncmp(szText, "[NZB] ", 6))
|
||||
{
|
||||
@@ -890,7 +908,7 @@ void NZBScriptController::AddMessage(Message::EKind eKind, bool bDefaultKind, Op
|
||||
}
|
||||
else
|
||||
{
|
||||
ScriptController::AddMessage(eKind, bDefaultKind, eMessageTarget, szText);
|
||||
ScriptController::AddMessage(eKind, bDefaultKind, szText);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user