예제 #1
0
/**
 * Removes old entries from (recent) history
 */
void HistoryCoordinator::ServiceWork()
{
	GuardedDownloadQueue downloadQueue = DownloadQueue::Guard();

	time_t minTime = Util::CurrentTime() - g_Options->GetKeepHistory() * 60*60*24;
	bool changed = false;
	int index = 0;

	// traversing in a reverse order to delete items in order they were added to history
	// (just to produce the log-messages in a more logical order)
	for (HistoryList::reverse_iterator it = downloadQueue->GetHistory()->rbegin(); it != downloadQueue->GetHistory()->rend(); )
	{
		HistoryInfo* historyInfo = (*it).get();
		if (historyInfo->GetKind() != HistoryInfo::hkDup && historyInfo->GetTime() < minTime)
		{
			if (g_Options->GetDupeCheck() && historyInfo->GetKind() == HistoryInfo::hkNzb)
			{
				// replace history element
				HistoryHide(downloadQueue, historyInfo, index);
				index++;
			}
			else
			{
				if (historyInfo->GetKind() == HistoryInfo::hkNzb)
				{
					DeleteDiskFiles(historyInfo->GetNzbInfo());
				}
				info("Collection %s removed from history", historyInfo->GetName());

				downloadQueue->GetHistory()->erase(downloadQueue->GetHistory()->end() - 1 - index);
			}

			it = downloadQueue->GetHistory()->rbegin() + index;
			changed = true;
		}
		else
		{
			it++;
			index++;
		}
	}

	if (changed)
	{
		downloadQueue->HistoryChanged();
		downloadQueue->Save();
	}
}
예제 #2
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());
}
예제 #3
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());
	}
}