Example #1
0
void PrePostProcessor::CheckPostQueue()
{
	GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();

	size_t countBefore = m_activeJobs.size();
	CheckRequestPar(downloadQueue);
	CleanupJobs(downloadQueue);
	bool changed = m_activeJobs.size() != countBefore;

	bool allowPar;
	while (CanRunMoreJobs(&allowPar) && !IsStopped())
	{
		NzbInfo* postJob = PickNextJob(downloadQueue, allowPar);
		if (!postJob)
		{
			break;
		}

		m_activeJobs.push_back(postJob);

		PostInfo* postInfo = postJob->GetPostInfo();
		if (postInfo->GetStage() == PostInfo::ptQueued &&
			(!g_Options->GetPausePostProcess() || postInfo->GetNzbInfo()->GetForcePriority()))
		{
			StartJob(downloadQueue, postInfo, allowPar);
			CheckRequestPar(downloadQueue);
			CleanupJobs(downloadQueue);
			changed = true;
		}
	}

	if (changed)
	{
		downloadQueue->Save();
		UpdatePauseState();
	}

	Util::SetStandByMode(m_activeJobs.empty());
}
Example #2
0
void PrePostProcessor::StartJob(DownloadQueue* pDownloadQueue, PostInfo* pPostInfo)
{
#ifndef DISABLE_PARCHECK
	if (pPostInfo->GetNZBInfo()->GetRenameStatus() == NZBInfo::rsNone)
	{
		UpdatePauseState(g_pOptions->GetParPauseQueue(), "par-rename");
		m_ParCoordinator.StartParRenameJob(pPostInfo);
		return;
	}
	else if (pPostInfo->GetNZBInfo()->GetParStatus() == NZBInfo::psNone)
	{
		if (m_ParCoordinator.FindMainPars(pPostInfo->GetNZBInfo()->GetDestDir(), NULL))
		{
			UpdatePauseState(g_pOptions->GetParPauseQueue(), "par-check");
			m_ParCoordinator.StartParCheckJob(pPostInfo);
		}
		else
		{
			info("Nothing to par-check for %s", pPostInfo->GetInfoName());
			pPostInfo->GetNZBInfo()->SetParStatus(NZBInfo::psSkipped);
			pPostInfo->SetWorking(false);
			pPostInfo->SetStage(PostInfo::ptQueued);
		}
		return;
	}
#endif

	NZBParameter* pUnpackParameter = pPostInfo->GetNZBInfo()->GetParameters()->Find("*Unpack:", false);
	bool bUnpackParam = !(pUnpackParameter && !strcasecmp(pUnpackParameter->GetValue(), "no"));
	bool bUnpack = bUnpackParam && (pPostInfo->GetNZBInfo()->GetUnpackStatus() == NZBInfo::usNone);

	bool bParFailed = pPostInfo->GetNZBInfo()->GetParStatus() == NZBInfo::psFailure ||
		pPostInfo->GetNZBInfo()->GetParStatus() == NZBInfo::psRepairPossible ||
		pPostInfo->GetNZBInfo()->GetParStatus() == NZBInfo::psManual;

	bool bCleanup = !bUnpack &&
		pPostInfo->GetNZBInfo()->GetCleanupStatus() == NZBInfo::csNone &&
		(pPostInfo->GetNZBInfo()->GetParStatus() == NZBInfo::psSuccess ||
		 (pPostInfo->GetNZBInfo()->GetUnpackStatus() == NZBInfo::usSuccess &&
		  pPostInfo->GetNZBInfo()->GetParStatus() != NZBInfo::psFailure)) &&
		strlen(g_pOptions->GetExtCleanupDisk()) > 0;

	bool bMoveInter = !bUnpack &&
		pPostInfo->GetNZBInfo()->GetMoveStatus() == NZBInfo::msNone &&
		pPostInfo->GetNZBInfo()->GetUnpackStatus() != NZBInfo::usFailure &&
		pPostInfo->GetNZBInfo()->GetParStatus() != NZBInfo::psFailure &&
		pPostInfo->GetNZBInfo()->GetParStatus() != NZBInfo::psManual &&
		strlen(g_pOptions->GetInterDir()) > 0 &&
		!strncmp(pPostInfo->GetNZBInfo()->GetDestDir(), g_pOptions->GetInterDir(), strlen(g_pOptions->GetInterDir()));

	// TODO: check if download has pp-scripts defined
	bool bPostScript = true;

	if (bUnpack && bParFailed)
	{
		warn("Skipping unpack due to %s for %s",
			pPostInfo->GetNZBInfo()->GetParStatus() == NZBInfo::psManual ? "required par-repair" : "par-failure",
			pPostInfo->GetInfoName());
		pPostInfo->GetNZBInfo()->SetUnpackStatus(NZBInfo::usSkipped);
		bUnpack = false;
	}

	if (!bUnpack && !bMoveInter && !bPostScript)
	{
		pPostInfo->SetStage(PostInfo::ptFinished);
		return;
	}

	pPostInfo->SetProgressLabel(bUnpack ? "Unpacking" : bMoveInter ? "Moving" : "Executing post-process-script");
	pPostInfo->SetWorking(true);
	pPostInfo->SetStage(bUnpack ? PostInfo::ptUnpacking : bMoveInter ? PostInfo::ptMoving : PostInfo::ptExecutingScript);
	pPostInfo->SetFileProgress(0);
	pPostInfo->SetStageProgress(0);
	SaveQueue(pDownloadQueue);

	if (!pPostInfo->GetStartTime())
	{
		pPostInfo->SetStartTime(time(NULL));
	}
	pPostInfo->SetStageTime(time(NULL));

	if (bUnpack)
	{
		UpdatePauseState(g_pOptions->GetUnpackPauseQueue(), "unpack");
		UnpackController::StartJob(pPostInfo);
	}
	else if (bCleanup)
	{
		UpdatePauseState(g_pOptions->GetUnpackPauseQueue() || g_pOptions->GetScriptPauseQueue(), "cleanup");
		CleanupController::StartJob(pPostInfo);
	}
	else if (bMoveInter)
	{
		UpdatePauseState(g_pOptions->GetUnpackPauseQueue() || g_pOptions->GetScriptPauseQueue(), "move");
		MoveController::StartJob(pPostInfo);
	}
	else
	{
		UpdatePauseState(g_pOptions->GetScriptPauseQueue(), "post-process-script");
		PostScriptController::StartJob(pPostInfo);
	}
}
Example #3
0
void PrePostProcessor::CheckPostQueue()
{
	DownloadQueue* pDownloadQueue = g_pQueueCoordinator->LockQueue();

	if (!pDownloadQueue->GetPostQueue()->empty())
	{
		PostInfo* pPostInfo = pDownloadQueue->GetPostQueue()->front();
		if (!pPostInfo->GetWorking())
		{
#ifndef DISABLE_PARCHECK
			if (pPostInfo->GetRequestParCheck() && pPostInfo->GetNZBInfo()->GetParStatus() <= NZBInfo::psSkipped &&
				g_pOptions->GetParCheck() != Options::pcManual)
			{
				pPostInfo->GetNZBInfo()->SetParStatus(NZBInfo::psNone);
				pPostInfo->SetRequestParCheck(false);
				pPostInfo->SetStage(PostInfo::ptQueued);
				pPostInfo->GetNZBInfo()->GetScriptStatuses()->Clear();
				DeletePostThread(pPostInfo);
			}
			else if (pPostInfo->GetRequestParCheck() && pPostInfo->GetNZBInfo()->GetParStatus() <= NZBInfo::psSkipped &&
				g_pOptions->GetParCheck() == Options::pcManual)
			{
				pPostInfo->SetRequestParCheck(false);
				pPostInfo->GetNZBInfo()->SetParStatus(NZBInfo::psManual);
				DeletePostThread(pPostInfo);

				FileInfo* pFileInfo = GetQueueGroup(pDownloadQueue, pPostInfo->GetNZBInfo());
				if (pFileInfo)
				{
					info("Downloading all remaining files for manual par-check for %s", pPostInfo->GetNZBInfo()->GetName());
					g_pQueueCoordinator->GetQueueEditor()->LockedEditEntry(pDownloadQueue, pFileInfo->GetID(), false, QueueEditor::eaGroupResume, 0, NULL);
					pPostInfo->SetStage(PostInfo::ptFinished);
					pPostInfo->GetNZBInfo()->SetPostProcess(false);
				}
				else
				{
					info("There are no par-files remain for download for %s", pPostInfo->GetNZBInfo()->GetName());
					pPostInfo->SetStage(PostInfo::ptQueued);
				}
			}
			else if (pPostInfo->GetRequestParRename())
			{
				pPostInfo->GetNZBInfo()->SetRenameStatus(NZBInfo::rsNone);
				pPostInfo->SetRequestParRename(false);
				pPostInfo->SetStage(PostInfo::ptQueued);
				DeletePostThread(pPostInfo);
			}

#endif
			if (pPostInfo->GetDeleted())
			{
				pPostInfo->SetStage(PostInfo::ptFinished);
			}

			if (pPostInfo->GetStage() == PostInfo::ptQueued && !g_pOptions->GetPausePostProcess())
			{
				DeletePostThread(pPostInfo);
				StartJob(pDownloadQueue, pPostInfo);
			}
			else if (pPostInfo->GetStage() == PostInfo::ptFinished)
			{
				UpdatePauseState(false, NULL);
				JobCompleted(pDownloadQueue, pPostInfo);
			}
			else if (!g_pOptions->GetPausePostProcess())
			{
				error("Internal error: invalid state in post-processor");
			}
		}
	}
	
	g_pQueueCoordinator->UnlockQueue();
}
Example #4
0
void PrePostProcessor::StartJob(DownloadQueue* downloadQueue, PostInfo* postInfo)
{
	if (!postInfo->GetStartTime())
	{
		postInfo->SetStartTime(Util::CurrentTime());
	}

#ifndef DISABLE_PARCHECK
	if (postInfo->GetNzbInfo()->GetRenameStatus() == NzbInfo::rsNone &&
		postInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsNone)
	{
		UpdatePauseState(g_Options->GetParPauseQueue(), "par-rename");
		m_parCoordinator.StartParRenameJob(postInfo);
		return;
	}
	else if (postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psNone &&
		postInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsNone)
	{
		if (ParParser::FindMainPars(postInfo->GetNzbInfo()->GetDestDir(), nullptr))
		{
			UpdatePauseState(g_Options->GetParPauseQueue(), "par-check");
			m_parCoordinator.StartParCheckJob(postInfo);
		}
		else
		{
			postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo,
				"Nothing to par-check for %s", postInfo->GetNzbInfo()->GetName());
			postInfo->GetNzbInfo()->SetParStatus(NzbInfo::psSkipped);
			postInfo->SetWorking(false);
			postInfo->SetStage(PostInfo::ptQueued);
		}
		return;
	}
	else if (postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psSkipped &&
		((g_Options->GetParScan() != Options::psDupe &&
		  postInfo->GetNzbInfo()->CalcHealth() < postInfo->GetNzbInfo()->CalcCriticalHealth(false) &&
		  postInfo->GetNzbInfo()->CalcCriticalHealth(false) < 1000) ||
		  postInfo->GetNzbInfo()->CalcHealth() == 0) &&
		ParParser::FindMainPars(postInfo->GetNzbInfo()->GetDestDir(), nullptr))
	{
		if (postInfo->GetNzbInfo()->CalcHealth() == 0)
		{
			postInfo->GetNzbInfo()->PrintMessage(Message::mkWarning,
				"Skipping par-check for %s due to health 0%%", postInfo->GetNzbInfo()->GetName());
		}
		else
		{
			postInfo->GetNzbInfo()->PrintMessage(Message::mkWarning,
				"Skipping par-check for %s due to health %.1f%% below critical %.1f%%",
				postInfo->GetNzbInfo()->GetName(),
				postInfo->GetNzbInfo()->CalcHealth() / 10.0, postInfo->GetNzbInfo()->CalcCriticalHealth(false) / 10.0);
		}
		postInfo->GetNzbInfo()->SetParStatus(NzbInfo::psFailure);
		return;
	}
	else if (postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psSkipped &&
		postInfo->GetNzbInfo()->GetFailedSize() - postInfo->GetNzbInfo()->GetParFailedSize() > 0 &&
		ParParser::FindMainPars(postInfo->GetNzbInfo()->GetDestDir(), nullptr))
	{
		postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo,
			"Collection %s with health %.1f%% needs par-check",
			postInfo->GetNzbInfo()->GetName(), postInfo->GetNzbInfo()->CalcHealth() / 10.0);
		postInfo->SetRequestParCheck(true);
		return;
	}
#endif

	NzbParameter* unpackParameter = postInfo->GetNzbInfo()->GetParameters()->Find("*Unpack:", false);
	bool unpackParam = !(unpackParameter && !strcasecmp(unpackParameter->GetValue(), "no"));
	bool unpack = unpackParam && postInfo->GetNzbInfo()->GetUnpackStatus() == NzbInfo::usNone &&
		postInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsNone;

	bool parFailed = postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psFailure ||
		postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psRepairPossible ||
		postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psManual;

	bool cleanup = !unpack &&
		postInfo->GetNzbInfo()->GetCleanupStatus() == NzbInfo::csNone &&
		!Util::EmptyStr(g_Options->GetExtCleanupDisk()) &&
		((postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psSuccess &&
		  postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usFailure &&
		  postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usSpace &&
		  postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usPassword) ||
		 (postInfo->GetNzbInfo()->GetUnpackStatus() == NzbInfo::usSuccess &&
		  postInfo->GetNzbInfo()->GetParStatus() != NzbInfo::psFailure) ||
		 ((postInfo->GetNzbInfo()->GetUnpackStatus() == NzbInfo::usNone ||
		   postInfo->GetNzbInfo()->GetUnpackStatus() == NzbInfo::usSkipped) &&
		  (postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psNone ||
		   postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psSkipped) &&
		  postInfo->GetNzbInfo()->CalcHealth() == 1000));

	bool moveInter = !unpack &&
		postInfo->GetNzbInfo()->GetMoveStatus() == NzbInfo::msNone &&
		postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usFailure &&
		postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usSpace &&
		postInfo->GetNzbInfo()->GetUnpackStatus() != NzbInfo::usPassword &&
		postInfo->GetNzbInfo()->GetParStatus() != NzbInfo::psFailure &&
		postInfo->GetNzbInfo()->GetParStatus() != NzbInfo::psManual &&
		postInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsNone &&
		!Util::EmptyStr(g_Options->GetInterDir()) &&
		!strncmp(postInfo->GetNzbInfo()->GetDestDir(), g_Options->GetInterDir(), strlen(g_Options->GetInterDir())) &&
		postInfo->GetNzbInfo()->GetDestDir()[strlen(g_Options->GetInterDir())] == PATH_SEPARATOR;

	bool postScript = true;

	if (unpack && parFailed)
	{
		postInfo->GetNzbInfo()->PrintMessage(Message::mkWarning,
			"Skipping unpack for %s due to %s", postInfo->GetNzbInfo()->GetName(),
			postInfo->GetNzbInfo()->GetParStatus() == NzbInfo::psManual ? "required par-repair" : "par-failure");
		postInfo->GetNzbInfo()->SetUnpackStatus(NzbInfo::usSkipped);
		unpack = false;
	}

	if (!unpack && !moveInter && !postScript)
	{
		postInfo->SetStage(PostInfo::ptFinished);
		return;
	}

	postInfo->SetProgressLabel(unpack ? "Unpacking" : moveInter ? "Moving" : "Executing post-process-script");
	postInfo->SetWorking(true);
	postInfo->SetStage(unpack ? PostInfo::ptUnpacking : moveInter ? PostInfo::ptMoving : PostInfo::ptExecutingScript);
	postInfo->SetFileProgress(0);
	postInfo->SetStageProgress(0);

	downloadQueue->Save();

	postInfo->SetStageTime(Util::CurrentTime());

	if (unpack)
	{
		UpdatePauseState(g_Options->GetUnpackPauseQueue(), "unpack");
		UnpackController::StartJob(postInfo);
	}
	else if (cleanup)
	{
		UpdatePauseState(g_Options->GetUnpackPauseQueue() || g_Options->GetScriptPauseQueue(), "cleanup");
		CleanupController::StartJob(postInfo);
	}
	else if (moveInter)
	{
		UpdatePauseState(g_Options->GetUnpackPauseQueue() || g_Options->GetScriptPauseQueue(), "move");
		MoveController::StartJob(postInfo);
	}
	else
	{
		UpdatePauseState(g_Options->GetScriptPauseQueue(), "post-process-script");
		PostScriptController::StartJob(postInfo);
	}
}
Example #5
0
void PrePostProcessor::CheckPostQueue()
{
	GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();

	if (!m_curJob && m_jobCount > 0)
	{
		m_curJob = GetNextJob(downloadQueue);
	}

	if (m_curJob)
	{
		PostInfo* postInfo = m_curJob->GetPostInfo();
		if (!postInfo->GetWorking() && !IsNzbFileDownloading(m_curJob))
		{
#ifndef DISABLE_PARCHECK
			if (postInfo->GetRequestParCheck() &&
				(postInfo->GetNzbInfo()->GetParStatus() <= NzbInfo::psSkipped ||
				 (postInfo->GetForceRepair() && !postInfo->GetNzbInfo()->GetParFull())) &&
				g_Options->GetParCheck() != Options::pcManual)
			{
				postInfo->SetForceParFull(postInfo->GetNzbInfo()->GetParStatus() > NzbInfo::psSkipped);
				postInfo->GetNzbInfo()->SetParStatus(NzbInfo::psNone);
				postInfo->SetRequestParCheck(false);
				postInfo->SetStage(PostInfo::ptQueued);
				postInfo->GetNzbInfo()->GetScriptStatuses()->clear();
				DeletePostThread(postInfo);
			}
			else if (postInfo->GetRequestParCheck() && postInfo->GetNzbInfo()->GetParStatus() <= NzbInfo::psSkipped &&
				g_Options->GetParCheck() == Options::pcManual)
			{
				postInfo->SetRequestParCheck(false);
				postInfo->GetNzbInfo()->SetParStatus(NzbInfo::psManual);
				DeletePostThread(postInfo);

				if (!postInfo->GetNzbInfo()->GetFileList()->empty())
				{
					postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo,
						"Downloading all remaining files for manual par-check for %s", postInfo->GetNzbInfo()->GetName());
					downloadQueue->EditEntry(postInfo->GetNzbInfo()->GetId(), DownloadQueue::eaGroupResume, 0, nullptr);
					postInfo->SetStage(PostInfo::ptFinished);
				}
				else
				{
					postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo,
						"There are no par-files remain for download for %s", postInfo->GetNzbInfo()->GetName());
					postInfo->SetStage(PostInfo::ptQueued);
				}
			}

#endif
			if (postInfo->GetDeleted())
			{
				postInfo->SetStage(PostInfo::ptFinished);
			}

			if (postInfo->GetStage() == PostInfo::ptQueued &&
				(!g_Options->GetPausePostProcess() || postInfo->GetNzbInfo()->GetForcePriority()))
			{
				DeletePostThread(postInfo);
				StartJob(downloadQueue, postInfo);
			}
			else if (postInfo->GetStage() == PostInfo::ptFinished)
			{
				UpdatePauseState(false, nullptr);
				JobCompleted(downloadQueue, postInfo);
			}
			else if (!g_Options->GetPausePostProcess())
			{
				error("Internal error: invalid state in post-processor");
				// TODO: cancel (delete) current job
			}
		}
	}
}