Example #1
0
void PrePostProcessor::JobCompleted(DownloadQueue* downloadQueue, PostInfo* postInfo)
{
	NzbInfo* nzbInfo = postInfo->GetNzbInfo();

	if (postInfo->GetStartTime() > 0)
	{
		nzbInfo->SetPostTotalSec((int)(Util::CurrentTime() - postInfo->GetStartTime()));
		postInfo->SetStartTime(0);
	}

	DeletePostThread(postInfo);
	nzbInfo->LeavePostProcess();

	if (IsNzbFileCompleted(nzbInfo, true))
	{
		NzbCompleted(downloadQueue, nzbInfo, false);
	}

	if (nzbInfo == m_curJob)
	{
		m_curJob = nullptr;
	}
	m_jobCount--;

	downloadQueue->Save();
}
Example #2
0
void QueueScriptCoordinator::CheckQueue()
{
	if (m_stopped)
	{
		return;
	}

	m_curItem.reset();

	GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();
	Guard guard(m_queueMutex);

	NzbInfo* curNzbInfo = nullptr;
	Queue::iterator itCurItem;

	for (Queue::iterator it = m_queue.begin(); it != m_queue.end(); )
	{
		std::unique_ptr<QueueItem>& queueItem = *it;

		NzbInfo* nzbInfo = FindNzbInfo(downloadQueue, queueItem->GetNzbId());

		// in a case this nzb must not be processed further - delete queue script from queue
		EEvent event = queueItem->GetEvent();
		bool ignoreEvent = !nzbInfo ||
			(nzbInfo->GetDeleteStatus() != NzbInfo::dsNone && event != qeNzbDeleted && event != qeNzbMarked) ||
			(nzbInfo->GetMarkStatus() == NzbInfo::ksBad && event != qeNzbMarked);

		if (ignoreEvent)
		{
			it = m_queue.erase(it);
			if (curNzbInfo)
			{
				// process from the beginning, while "erase" invalidated "itCurItem"
				curNzbInfo = nullptr;
				it = m_queue.begin();
			}
			continue;
		}

		if (!m_curItem || queueItem->GetEvent() > m_curItem->GetEvent())
		{
			itCurItem = it;
			curNzbInfo = nzbInfo;
		}

		it++;
	}

	if (curNzbInfo)
	{
		m_curItem = std::move(*itCurItem);
		m_queue.erase(itCurItem);
		QueueScriptController::StartScript(curNzbInfo, m_curItem->GetScript(), m_curItem->GetEvent());
	}
}
Example #3
0
void PrePostProcessor::JobCompleted(DownloadQueue* downloadQueue, PostInfo* postInfo)
{
	NzbInfo* nzbInfo = postInfo->GetNzbInfo();

	nzbInfo->LeavePostProcess();

	if (nzbInfo->IsDownloadCompleted(true))
	{
		NzbCompleted(downloadQueue, nzbInfo, false);
	}

	m_queuedJobs--;
}
Example #4
0
NzbInfo* PrePostProcessor::GetNextJob(DownloadQueue* downloadQueue)
{
	NzbInfo* nzbInfo = nullptr;

	for (NzbInfo* nzbInfo1: downloadQueue->GetQueue())
	{
		if (nzbInfo1->GetPostInfo() && !g_QueueScriptCoordinator->HasJob(nzbInfo1->GetId(), nullptr) &&
			(!nzbInfo || nzbInfo1->GetPriority() > nzbInfo->GetPriority()) &&
			(!g_Options->GetPausePostProcess() || nzbInfo1->GetForcePriority()))
		{
			nzbInfo = nzbInfo1;
		}
	}

	return nzbInfo;
}
Example #5
0
void QueueScriptController::Run()
{
	ExecuteScript(m_script);

	SetLogPrefix(nullptr);

	if (m_markBad)
	{
		GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();
		NzbInfo* nzbInfo = downloadQueue->GetQueue()->Find(m_id);
		if (nzbInfo)
		{
			PrintMessage(Message::mkWarning, "Cancelling download and deleting %s", *m_nzbName);
			nzbInfo->SetDeleteStatus(NzbInfo::dsBad);
			downloadQueue->EditEntry(m_id, DownloadQueue::eaGroupDelete, 0, nullptr);
		}
	}

	g_QueueScriptCoordinator->CheckQueue();
}
Example #6
0
/*
 * Returns next URL for download.
 */
NzbInfo* UrlCoordinator::GetNextUrl(DownloadQueue* downloadQueue)
{
	bool pauseDownload = g_Options->GetPauseDownload();

	NzbInfo* nzbInfo = nullptr;

	for (NzbInfo* nzbInfo1 : downloadQueue->GetQueue())
	{
		if (nzbInfo1->GetKind() == NzbInfo::nkUrl &&
			nzbInfo1->GetUrlStatus() == NzbInfo::lsNone &&
			nzbInfo1->GetDeleteStatus() == NzbInfo::dsNone &&
			(!pauseDownload || g_Options->GetUrlForce()) &&
			(!nzbInfo || nzbInfo1->GetPriority() > nzbInfo->GetPriority()))
		{
			nzbInfo = nzbInfo1;
		}
	}

	return nzbInfo;
}
Example #7
0
NzbInfo* PrePostProcessor::PickNextJob(DownloadQueue* downloadQueue, bool allowPar)
{
	NzbInfo* nzbInfo = nullptr;

	for (NzbInfo* nzbInfo1: downloadQueue->GetQueue())
	{
		if (nzbInfo1->GetPostInfo() && !nzbInfo1->GetPostInfo()->GetWorking() &&
			!g_QueueScriptCoordinator->HasJob(nzbInfo1->GetId(), nullptr) &&
			nzbInfo1->GetDirectUnpackStatus() != NzbInfo::nsRunning &&
			(!nzbInfo || nzbInfo1->GetPriority() > nzbInfo->GetPriority()) &&
			(!g_Options->GetPausePostProcess() || nzbInfo1->GetForcePriority()) &&
			(allowPar || !nzbInfo1->GetPostInfo()->GetNeedParCheck()) &&
			(std::find(m_activeJobs.begin(), m_activeJobs.end(), nzbInfo1) == m_activeJobs.end()) &&
			nzbInfo1->IsDownloadCompleted(true))
		{
			nzbInfo = nzbInfo1;
		}
	}

	return nzbInfo;
}
Example #8
0
void QueueEditor::ReorderFiles(ItemList* itemList)
{
	if (itemList->size() == 0)
	{
		return;
	}

	EditItem& firstItem = itemList->front();
	NzbInfo* nzbInfo = firstItem.m_fileInfo->GetNzbInfo();
	uint32 insertPos = 0;

	// now can reorder
	for (EditItem& item : itemList)
	{
		FileInfo* fileInfo = item.m_fileInfo;

		// move file item
		FileList::iterator it2 = nzbInfo->GetFileList()->Find(fileInfo);
		if (it2 != nzbInfo->GetFileList()->end())
		{
			std::unique_ptr<FileInfo> movedFileInfo = std::move(*it2);
			nzbInfo->GetFileList()->erase(it2);
			nzbInfo->GetFileList()->insert(nzbInfo->GetFileList()->begin() + insertPos, std::move(movedFileInfo));
			insertPos++;
		}
	}
}
Example #9
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 #10
0
void QueueScriptController::AddMessage(Message::EKind kind, const char* text)
{
	const char* msgText = text + m_prefixLen;

	if (!strncmp(msgText, "[NZB] ", 6))
	{
		debug("Command %s detected", msgText + 6);
		if (!strncmp(msgText + 6, "NZBPR_", 6))
		{
			CString param = msgText + 6 + 6;
			char* value = strchr(param, '=');
			if (value)
			{
				*value = '\0';
				GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();
				NzbInfo* nzbInfo = QueueScriptCoordinator::FindNzbInfo(downloadQueue, m_id);
				if (nzbInfo)
				{
					nzbInfo->GetParameters()->SetParameter(param, value + 1);
				}
			}
			else
			{
				error("Invalid command \"%s\" received from %s", msgText, GetInfoName());
			}
		}
		else if (!strncmp(msgText + 6, "DIRECTORY=", 10) &&
			m_event == QueueScriptCoordinator::qeNzbDownloaded)
		{
			GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();
			NzbInfo* nzbInfo = QueueScriptCoordinator::FindNzbInfo(downloadQueue, m_id);
			if (nzbInfo)
			{
				nzbInfo->SetFinalDir(msgText + 6 + 10);
			}
		}
		else if (!strncmp(msgText + 6, "MARK=BAD", 8))
		{
			m_markBad = true;
			GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();
			NzbInfo* nzbInfo = QueueScriptCoordinator::FindNzbInfo(downloadQueue, m_id);
			if (nzbInfo)
			{
				SetLogPrefix(nullptr);
				PrintMessage(Message::mkWarning, "Marking %s as bad", *m_nzbName);
				SetLogPrefix(m_script->GetDisplayName());
				nzbInfo->SetMarkStatus(NzbInfo::ksBad);
			}
		}
		else
		{
			error("Invalid command \"%s\" received from %s", msgText, GetInfoName());
		}
	}
	else
	{
		NzbInfo* nzbInfo = nullptr;
		{
			GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();
			nzbInfo = QueueScriptCoordinator::FindNzbInfo(downloadQueue, m_id);
			if (nzbInfo)
			{
				nzbInfo->AddMessage(kind, text);
			}
		}

		if (!nzbInfo)
		{
			ScriptController::AddMessage(kind, text);
		}
	}
}
Example #11
0
void UrlCoordinator::UrlCompleted(UrlDownloader* urlDownloader)
{
	debug("URL downloaded");

	NzbInfo* nzbInfo = urlDownloader->GetNzbInfo();

	const char* origname;
	if (urlDownloader->GetOriginalFilename())
	{
		origname = urlDownloader->GetOriginalFilename();
	}
	else
	{
		origname = FileSystem::BaseFileName(nzbInfo->GetUrl());

		// TODO: decode URL escaping
	}

	CString filename = FileSystem::MakeValidFilename(origname);

	debug("Filename: [%s]", *filename);

	bool retry;

	{
		GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();

		// remove downloader from downloader list
		m_activeDownloads.erase(std::find(m_activeDownloads.begin(), m_activeDownloads.end(), urlDownloader));

		nzbInfo->SetActiveDownloads(0);

		retry = urlDownloader->GetStatus() == WebDownloader::adRetry && !nzbInfo->GetDeleting();

		if (nzbInfo->GetDeleting())
		{
			nzbInfo->SetDeleteStatus(NzbInfo::dsManual);
			nzbInfo->SetUrlStatus(NzbInfo::lsNone);
			nzbInfo->SetDeleting(false);
		}
		else if (urlDownloader->GetStatus() == WebDownloader::adFinished)
		{
			nzbInfo->SetUrlStatus(NzbInfo::lsFinished);
		}
		else if (urlDownloader->GetStatus() == WebDownloader::adFailed)
		{
			nzbInfo->SetUrlStatus(NzbInfo::lsFailed);
		}
		else if (urlDownloader->GetStatus() == WebDownloader::adRetry)
		{
			nzbInfo->SetUrlStatus(NzbInfo::lsNone);
		}

		if (!retry)
		{
			DownloadQueue::Aspect aspect = {DownloadQueue::eaUrlCompleted, downloadQueue, nzbInfo, nullptr};
			downloadQueue->Notify(&aspect);
		}
	}

	if (retry)
	{
		return;
	}

	if (nzbInfo->GetUrlStatus() == NzbInfo::lsFinished)
	{
		// add nzb-file to download queue
		Scanner::EAddStatus addStatus = g_Scanner->AddExternalFile(
			!Util::EmptyStr(nzbInfo->GetFilename()) ? nzbInfo->GetFilename() : *filename,
			!Util::EmptyStr(nzbInfo->GetCategory()) ? nzbInfo->GetCategory() : urlDownloader->GetCategory(),
			nzbInfo->GetPriority(), nzbInfo->GetDupeKey(), nzbInfo->GetDupeScore(), nzbInfo->GetDupeMode(),
			nzbInfo->GetParameters(), false, nzbInfo->GetAddUrlPaused(), nzbInfo,
			urlDownloader->GetOutputFilename(), nullptr, 0, nullptr);

		if (addStatus == Scanner::asSuccess)
		{
			// if scanner has successfully added nzb-file to queue, our pNZBInfo is
			// already removed from queue and destroyed
			return;
		}

		nzbInfo->SetUrlStatus(addStatus == Scanner::asFailed ? NzbInfo::lsScanFailed : NzbInfo::lsScanSkipped);
	}

	// the rest of function is only for failed URLs or for failed scans

	g_QueueScriptCoordinator->EnqueueScript(nzbInfo, QueueScriptCoordinator::qeUrlCompleted);

	std::unique_ptr<NzbInfo> oldNzbInfo;

	{
		GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();

		// delete URL from queue
		oldNzbInfo = downloadQueue->GetQueue()->Remove(nzbInfo);

		// add failed URL to history
		if (g_Options->GetKeepHistory() > 0 &&
			nzbInfo->GetUrlStatus() != NzbInfo::lsFinished &&
			!nzbInfo->GetAvoidHistory())
		{
			std::unique_ptr<HistoryInfo> historyInfo = std::make_unique<HistoryInfo>(std::move(oldNzbInfo));
			historyInfo->SetTime(Util::CurrentTime());
			downloadQueue->GetHistory()->Add(std::move(historyInfo), true);
			downloadQueue->HistoryChanged();
		}

		downloadQueue->Save();
	}

	if (oldNzbInfo)
	{
		g_DiskState->DiscardFiles(oldNzbInfo.get());
	}
}