Beispiel #1
0
void ParCoordinator::PostParChecker::StatDupeSources(DupeSourceList* pDupeSourceList)
{
	DownloadQueue* pDownloadQueue = DownloadQueue::Lock();

	int iTotalExtraParBlocks = 0;
	for (DupeSourceList::iterator it = pDupeSourceList->begin(); it != pDupeSourceList->end(); it++)
	{
		DupeSource* pDupeSource = *it;
		if (pDupeSource->GetUsedBlocks() > 0)
		{
			for (HistoryList::iterator it = pDownloadQueue->GetHistory()->begin(); it != pDownloadQueue->GetHistory()->end(); it++)
			{
				HistoryInfo* pHistoryInfo = *it;
				if (pHistoryInfo->GetKind() == HistoryInfo::hkNzb &&
					pHistoryInfo->GetNZBInfo()->GetID() == pDupeSource->GetID())
				{
					pHistoryInfo->GetNZBInfo()->SetExtraParBlocks(pHistoryInfo->GetNZBInfo()->GetExtraParBlocks() - pDupeSource->GetUsedBlocks());
				}
			}
		}
		iTotalExtraParBlocks += pDupeSource->GetUsedBlocks();
	}

	m_pPostInfo->GetNZBInfo()->SetExtraParBlocks(m_pPostInfo->GetNZBInfo()->GetExtraParBlocks() + iTotalExtraParBlocks);

	DownloadQueue::Unlock();
}
Beispiel #2
0
void PrePostProcessor::NZBCompleted(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo, bool bSaveQueue)
{
	if (g_pOptions->GetKeepHistory() > 0)
	{
		//remove old item for the same NZB
		for (HistoryList::iterator it = pDownloadQueue->GetHistoryList()->begin(); it != pDownloadQueue->GetHistoryList()->end(); it++)
		{
			HistoryInfo* pHistoryInfo = *it;
			if (pHistoryInfo->GetNZBInfo() == pNZBInfo)
			{
				delete pHistoryInfo;
				pDownloadQueue->GetHistoryList()->erase(it);
				break;
			}
		}

		HistoryInfo* pHistoryInfo = new HistoryInfo(pNZBInfo);
		pHistoryInfo->SetTime(time(NULL));
		pDownloadQueue->GetHistoryList()->push_front(pHistoryInfo);

		// park files
		int iParkedFiles = 0;
		int index = 0;
		for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); )
		{
			FileInfo* pFileInfo = *it;
			if (pFileInfo->GetNZBInfo() == pNZBInfo && !pFileInfo->GetDeleted())
			{
				detail("Park file %s", pFileInfo->GetFilename());
				g_pQueueCoordinator->DiscardDiskFile(pFileInfo);
				pDownloadQueue->GetFileQueue()->erase(it);
				pDownloadQueue->GetParkedFiles()->push_back(pFileInfo);
				it = pDownloadQueue->GetFileQueue()->begin() + index;
				iParkedFiles++;
			}
			else
			{
				it++;
				index++;
			}
		}
		pNZBInfo->SetParkedFileCount(iParkedFiles);

		if (bSaveQueue)
		{
			SaveQueue(pDownloadQueue);
		}

		info("Collection %s added to history", pNZBInfo->GetName());
	}
}
void HistoryCoordinator::AddToHistory(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo)
{
	//remove old item for the same NZB
	for (HistoryList::iterator it = pDownloadQueue->GetHistory()->begin(); it != pDownloadQueue->GetHistory()->end(); it++)
	{
		HistoryInfo* pHistoryInfo = *it;
		if (pHistoryInfo->GetNZBInfo() == pNZBInfo)
		{
			delete pHistoryInfo;
			pDownloadQueue->GetHistory()->erase(it);
			break;
		}
	}

	HistoryInfo* pHistoryInfo = new HistoryInfo(pNZBInfo);
	pHistoryInfo->SetTime(time(NULL));
	pDownloadQueue->GetHistory()->push_front(pHistoryInfo);
	pDownloadQueue->GetQueue()->Remove(pNZBInfo);

	if (pNZBInfo->GetDeleteStatus() == NZBInfo::dsNone)
	{
		// park files and delete files marked for deletion
		int iParkedFiles = 0;
		for (FileList::iterator it = pNZBInfo->GetFileList()->begin(); it != pNZBInfo->GetFileList()->end(); )
		{
			FileInfo* pFileInfo = *it;
			if (!pFileInfo->GetDeleted())
			{
				detail("Parking file %s", pFileInfo->GetFilename());
				g_pQueueCoordinator->DiscardDiskFile(pFileInfo);
				iParkedFiles++;
				it++;
			}
			else
			{
				// since we removed pNZBInfo from queue we need to take care of removing file infos marked for deletion
				pNZBInfo->GetFileList()->erase(it);
				delete pFileInfo;
				it = pNZBInfo->GetFileList()->begin() + iParkedFiles;
			}
		}
		pNZBInfo->SetParkedFileCount(iParkedFiles);
	}
	else
	{
		pNZBInfo->GetFileList()->Clear();
	}

	pNZBInfo->PrintMessage(Message::mkInfo, "Collection %s added to history", pNZBInfo->GetName());
}
Beispiel #4
0
bool PrePostProcessor::HistoryEdit(IDList* pIDList, EEditAction eAction, int iOffset, const char* szText)
{
	bool bOK = false;

	DownloadQueue* pDownloadQueue = g_pQueueCoordinator->LockQueue();

	for (IDList::iterator itID = pIDList->begin(); itID != pIDList->end(); itID++)
	{
		int iID = *itID;
		for (HistoryList::iterator itHistory = pDownloadQueue->GetHistoryList()->begin(); itHistory != pDownloadQueue->GetHistoryList()->end(); itHistory++)
		{
			HistoryInfo* pHistoryInfo = *itHistory;
			if (pHistoryInfo->GetID() == iID)
			{
				switch (eAction)
				{
					case eaHistoryDelete:
						HistoryDelete(pDownloadQueue, itHistory, pHistoryInfo);
						break;

					case eaHistoryReturn:
					case eaHistoryProcess:
						HistoryReturn(pDownloadQueue, itHistory, pHistoryInfo, eAction == eaHistoryProcess);
						break;

					case eaHistorySetParameter:
						HistorySetParameter(pHistoryInfo, szText);
						break;
						
					default:
						// nothing, just to avoid compiler warning
						break;
				}

				bOK = true;
				break;
			}
		}
	}

	if (bOK)
	{
		SaveQueue(pDownloadQueue);
	}

	g_pQueueCoordinator->UnlockQueue();

	return bOK;
}
Beispiel #5
0
NzbInfo* QueueScriptCoordinator::FindNzbInfo(DownloadQueue* downloadQueue, int nzbId)
{
	NzbInfo* nzbInfo = downloadQueue->GetQueue()->Find(nzbId);
	if (nzbInfo)
	{
		return nzbInfo;
	}

	HistoryInfo* historyInfo = downloadQueue->GetHistory()->Find(nzbId);
	if (historyInfo)
	{
		return historyInfo->GetNzbInfo();
	}

	return nullptr;
}
void HistoryCoordinator::PrepareEdit(DownloadQueue* downloadQueue, IdList* idList, DownloadQueue::EEditAction action)
{
	// First pass: when marking multiple items - mark them bad without performing the mark-logic,
	// this will later (on second step) avoid moving other items to download queue, if they are marked bad too.
	if (action == DownloadQueue::eaHistoryMarkBad)
	{
		for (int id : *idList)
		{
			HistoryInfo* historyInfo = downloadQueue->GetHistory()->Find(id);
			if (historyInfo && historyInfo->GetKind() == HistoryInfo::hkNzb)
			{
				historyInfo->GetNzbInfo()->SetMarkStatus(NzbInfo::ksBad);
			}
		}
	}
}
void HistoryCoordinator::PrepareEdit(DownloadQueue* pDownloadQueue, IDList* pIDList, DownloadQueue::EEditAction eAction)
{
	// First pass: when marking multiple items - mark them bad without performing the mark-logic,
	// this will later (on second step) avoid moving other items to download queue, if they are marked bad too.
	if (eAction == DownloadQueue::eaHistoryMarkBad)
	{
		for (IDList::iterator itID = pIDList->begin(); itID != pIDList->end(); itID++)
		{
			int iID = *itID;
			HistoryInfo* pHistoryInfo = pDownloadQueue->GetHistory()->Find(iID);
			if (pHistoryInfo && pHistoryInfo->GetKind() == HistoryInfo::hkNzb)
			{
				pHistoryInfo->GetNZBInfo()->SetMarkStatus(NZBInfo::ksBad);
			}
		}
	}
}
/**
 * Removes old entries from (recent) history
 */
void HistoryCoordinator::ServiceWork()
{
	DownloadQueue* pDownloadQueue = DownloadQueue::Lock();

	time_t tMinTime = time(NULL) - g_pOptions->GetKeepHistory() * 60*60*24;
	bool bChanged = 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 = pDownloadQueue->GetHistory()->rbegin(); it != pDownloadQueue->GetHistory()->rend(); )
	{
		HistoryInfo* pHistoryInfo = *it;
		if (pHistoryInfo->GetKind() != HistoryInfo::hkDup && pHistoryInfo->GetTime() < tMinTime)
		{
			if (g_pOptions->GetDupeCheck() && pHistoryInfo->GetKind() == HistoryInfo::hkNzb)
			{
				// replace history element
				HistoryHide(pDownloadQueue, pHistoryInfo, index);
				index++;
			}
			else
			{
				char szNiceName[1024];
				pHistoryInfo->GetName(szNiceName, 1024);

				pDownloadQueue->GetHistory()->erase(pDownloadQueue->GetHistory()->end() - 1 - index);
				
				if (pHistoryInfo->GetKind() == HistoryInfo::hkNzb)
				{
					DeleteDiskFiles(pHistoryInfo->GetNZBInfo());
				}
				info("Collection %s removed from history", szNiceName);

				delete pHistoryInfo;
			}

			it = pDownloadQueue->GetHistory()->rbegin() + index;
			bChanged = true;
		}
		else
		{
			it++;
			index++;
		}
	}

	if (bChanged)
	{
		pDownloadQueue->Save();
	}

	DownloadQueue::Unlock();
}
Beispiel #9
0
/**
 * Removes old entries from history
 */
void PrePostProcessor::CheckHistory()
{
	DownloadQueue* pDownloadQueue = g_pQueueCoordinator->LockQueue();

	time_t tMinTime = time(NULL) - g_pOptions->GetKeepHistory() * 60000;
	bool bChanged = 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 = pDownloadQueue->GetHistoryList()->rbegin(); it != pDownloadQueue->GetHistoryList()->rend(); )
	{
		HistoryInfo* pHistoryInfo = *it;
		if (pHistoryInfo->GetTime() < tMinTime)
		{
			char szNiceName[1024];
			pHistoryInfo->GetName(szNiceName, 1024);
			pDownloadQueue->GetHistoryList()->erase(pDownloadQueue->GetHistoryList()->end() - 1 - index);
			delete pHistoryInfo;
			info("Collection %s removed from history", szNiceName);
			it = pDownloadQueue->GetHistoryList()->rbegin() + index;
			bChanged = true;
		}
		else
		{
			it++;
			index++;
		}
	}

	if (bChanged)
	{
		SaveQueue(pDownloadQueue);
	}

	g_pQueueCoordinator->UnlockQueue();
}
void HistoryCoordinator::HistoryHide(DownloadQueue* pDownloadQueue, HistoryInfo* pHistoryInfo, int rindex)
{
	char szNiceName[1024];
	pHistoryInfo->GetName(szNiceName, 1024);

	// replace history element
	DupInfo* pDupInfo = new DupInfo();
	pDupInfo->SetID(pHistoryInfo->GetNZBInfo()->GetID());
	pDupInfo->SetName(pHistoryInfo->GetNZBInfo()->GetName());
	pDupInfo->SetDupeKey(pHistoryInfo->GetNZBInfo()->GetDupeKey());
	pDupInfo->SetDupeScore(pHistoryInfo->GetNZBInfo()->GetDupeScore());
	pDupInfo->SetDupeMode(pHistoryInfo->GetNZBInfo()->GetDupeMode());
	pDupInfo->SetSize(pHistoryInfo->GetNZBInfo()->GetSize());
	pDupInfo->SetFullContentHash(pHistoryInfo->GetNZBInfo()->GetFullContentHash());
	pDupInfo->SetFilteredContentHash(pHistoryInfo->GetNZBInfo()->GetFilteredContentHash());

	pDupInfo->SetStatus(
		pHistoryInfo->GetNZBInfo()->GetMarkStatus() == NZBInfo::ksGood ? DupInfo::dsGood :
		pHistoryInfo->GetNZBInfo()->GetMarkStatus() == NZBInfo::ksBad ? DupInfo::dsBad :
		pHistoryInfo->GetNZBInfo()->GetMarkStatus() == NZBInfo::ksSuccess ? DupInfo::dsSuccess :
		pHistoryInfo->GetNZBInfo()->GetDeleteStatus() == NZBInfo::dsDupe ? DupInfo::dsDupe :
		pHistoryInfo->GetNZBInfo()->GetDeleteStatus() == NZBInfo::dsManual ||
		pHistoryInfo->GetNZBInfo()->GetDeleteStatus() == NZBInfo::dsGood ||
		pHistoryInfo->GetNZBInfo()->GetDeleteStatus() == NZBInfo::dsCopy ? DupInfo::dsDeleted :
		pHistoryInfo->GetNZBInfo()->IsDupeSuccess() ? DupInfo::dsSuccess :
		DupInfo::dsFailed);

	HistoryInfo* pNewHistoryInfo = new HistoryInfo(pDupInfo);
	pNewHistoryInfo->SetTime(pHistoryInfo->GetTime());
	(*pDownloadQueue->GetHistory())[pDownloadQueue->GetHistory()->size() - 1 - rindex] = pNewHistoryInfo;

	DeleteDiskFiles(pHistoryInfo->GetNZBInfo());

	delete pHistoryInfo;
	info("Collection %s removed from history", szNiceName);
}
Beispiel #11
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();
	}
}
bool HistoryCoordinator::EditList(DownloadQueue* pDownloadQueue, IDList* pIDList, DownloadQueue::EEditAction eAction, int iOffset, const char* szText)
{
	bool bOK = false;
	PrepareEdit(pDownloadQueue, pIDList, eAction);

	for (IDList::iterator itID = pIDList->begin(); itID != pIDList->end(); itID++)
	{
		int iID = *itID;
		for (HistoryList::iterator itHistory = pDownloadQueue->GetHistory()->begin(); itHistory != pDownloadQueue->GetHistory()->end(); itHistory++)
		{
			HistoryInfo* pHistoryInfo = *itHistory;
			if (pHistoryInfo->GetID() == iID)
			{
				bOK = true;

				switch (eAction)
				{
					case DownloadQueue::eaHistoryDelete:
					case DownloadQueue::eaHistoryFinalDelete:
						HistoryDelete(pDownloadQueue, itHistory, pHistoryInfo, eAction == DownloadQueue::eaHistoryFinalDelete);
						break;

					case DownloadQueue::eaHistoryReturn:
					case DownloadQueue::eaHistoryProcess:
						HistoryReturn(pDownloadQueue, itHistory, pHistoryInfo, eAction == DownloadQueue::eaHistoryProcess);
						break;

					case DownloadQueue::eaHistoryRedownload:
						HistoryRedownload(pDownloadQueue, itHistory, pHistoryInfo, false);
						break;

 					case DownloadQueue::eaHistorySetParameter:
						bOK = HistorySetParameter(pHistoryInfo, szText);
						break;

 					case DownloadQueue::eaHistorySetCategory:
						bOK = HistorySetCategory(pHistoryInfo, szText);
						break;

 					case DownloadQueue::eaHistorySetName:
						bOK = HistorySetName(pHistoryInfo, szText);
						break;

					case DownloadQueue::eaHistorySetDupeKey:
					case DownloadQueue::eaHistorySetDupeScore:
					case DownloadQueue::eaHistorySetDupeMode:
					case DownloadQueue::eaHistorySetDupeBackup:
						HistorySetDupeParam(pHistoryInfo, eAction, szText);
						break;

					case DownloadQueue::eaHistoryMarkBad:
						g_pDupeCoordinator->HistoryMark(pDownloadQueue, pHistoryInfo, NZBInfo::ksBad);
						break;

					case DownloadQueue::eaHistoryMarkGood:
						g_pDupeCoordinator->HistoryMark(pDownloadQueue, pHistoryInfo, NZBInfo::ksGood);
						break;

					case DownloadQueue::eaHistoryMarkSuccess:
						g_pDupeCoordinator->HistoryMark(pDownloadQueue, pHistoryInfo, NZBInfo::ksSuccess);
						break;

					default:
						// nothing, just to avoid compiler warning
						break;
				}

				break;
			}
		}
	}

	if (bOK)
	{
		pDownloadQueue->Save();
	}

	return bOK;
}
Beispiel #13
0
void HistoryBinCommand::Execute()
{
	SNZBHistoryRequest HistoryRequest;
	if (!ReceiveRequest(&HistoryRequest, sizeof(HistoryRequest)))
	{
		return;
	}

	SNZBHistoryResponse HistoryResponse;
	memset(&HistoryResponse, 0, sizeof(HistoryResponse));
	HistoryResponse.m_MessageBase.m_iSignature = htonl(NZBMESSAGE_SIGNATURE);
	HistoryResponse.m_MessageBase.m_iStructSize = htonl(sizeof(HistoryResponse));
	HistoryResponse.m_iEntrySize = htonl(sizeof(SNZBHistoryResponseEntry));

	char* buf = NULL;
	int bufsize = 0;

	// Make a data structure and copy all the elements of the list into it
	DownloadQueue* pDownloadQueue = g_pQueueCoordinator->LockQueue();

	// calculate required buffer size for nzbs
	int iNrEntries = pDownloadQueue->GetHistoryList()->size();
	bufsize += iNrEntries * sizeof(SNZBHistoryResponseEntry);
	for (HistoryList::iterator it = pDownloadQueue->GetHistoryList()->begin(); it != pDownloadQueue->GetHistoryList()->end(); it++)
	{
		HistoryInfo* pHistoryInfo = *it;
		char szNicename[1024];
		pHistoryInfo->GetName(szNicename, sizeof(szNicename));
		bufsize += strlen(szNicename) + 1;
		// align struct to 4-bytes, needed by ARM-processor (and may be others)
		bufsize += bufsize % 4 > 0 ? 4 - bufsize % 4 : 0;
	}

	buf = (char*) malloc(bufsize);
	char* bufptr = buf;

	// write nzb entries
	for (HistoryList::iterator it = pDownloadQueue->GetHistoryList()->begin(); it != pDownloadQueue->GetHistoryList()->end(); it++)
	{
		HistoryInfo* pHistoryInfo = *it;
		SNZBHistoryResponseEntry* pListAnswer = (SNZBHistoryResponseEntry*) bufptr;
		pListAnswer->m_iID					= htonl(pHistoryInfo->GetID());
		pListAnswer->m_iKind				= htonl((int)pHistoryInfo->GetKind());
		pListAnswer->m_tTime				= htonl((int)pHistoryInfo->GetTime());

		char szNicename[1024];
		pHistoryInfo->GetName(szNicename, sizeof(szNicename));
		pListAnswer->m_iNicenameLen			= htonl(strlen(szNicename) + 1);

		if (pHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo)
		{
			NZBInfo* pNZBInfo = pHistoryInfo->GetNZBInfo();
			unsigned long iSizeHi, iSizeLo;
			Util::SplitInt64(pNZBInfo->GetSize(), &iSizeHi, &iSizeLo);
			pListAnswer->m_iSizeLo				= htonl(iSizeLo);
			pListAnswer->m_iSizeHi				= htonl(iSizeHi);
			pListAnswer->m_iFileCount			= htonl(pNZBInfo->GetFileCount());
			pListAnswer->m_iParStatus			= htonl(pNZBInfo->GetParStatus());
			pListAnswer->m_iScriptStatus		= htonl(pNZBInfo->GetScriptStatus());
		}
		else if (pHistoryInfo->GetKind() == HistoryInfo::hkUrlInfo)
		{
			UrlInfo* pUrlInfo = pHistoryInfo->GetUrlInfo();
			pListAnswer->m_iUrlStatus			= htonl(pUrlInfo->GetStatus());
		}

		bufptr += sizeof(SNZBHistoryResponseEntry);
		strcpy(bufptr, szNicename);
		bufptr += ntohl(pListAnswer->m_iNicenameLen);
		// align struct to 4-bytes, needed by ARM-processor (and may be others)
		if ((size_t)bufptr % 4 > 0)
		{
			pListAnswer->m_iNicenameLen = htonl(ntohl(pListAnswer->m_iNicenameLen) + 4 - (size_t)bufptr % 4);
			memset(bufptr, 0, 4 - (size_t)bufptr % 4); //suppress valgrind warning "uninitialized data"
			bufptr += 4 - (size_t)bufptr % 4;
		}
	}

	g_pQueueCoordinator->UnlockQueue();

	HistoryResponse.m_iNrTrailingEntries = htonl(iNrEntries);
	HistoryResponse.m_iTrailingDataLength = htonl(bufsize);

	// Send the request answer
	send(m_iSocket, (char*) &HistoryResponse, sizeof(HistoryResponse), 0);

	// Send the data
	if (bufsize > 0)
	{
		send(m_iSocket, buf, bufsize, 0);
	}

	free(buf);
}
Beispiel #14
0
bool HistoryCoordinator::EditList(DownloadQueue* downloadQueue, IdList* idList, DownloadQueue::EEditAction action, int offset, const char* text)
{
	bool ok = false;
	PrepareEdit(downloadQueue, idList, action);

	for (int id : *idList)
	{
		for (HistoryList::iterator itHistory = downloadQueue->GetHistory()->begin(); itHistory != downloadQueue->GetHistory()->end(); itHistory++)
		{
			HistoryInfo* historyInfo = (*itHistory).get();
			if (historyInfo->GetId() == id)
			{
				ok = true;

				switch (action)
				{
					case DownloadQueue::eaHistoryDelete:
					case DownloadQueue::eaHistoryFinalDelete:
						HistoryDelete(downloadQueue, itHistory, historyInfo, action == DownloadQueue::eaHistoryFinalDelete);
						break;

					case DownloadQueue::eaHistoryReturn:
						HistoryReturn(downloadQueue, itHistory, historyInfo);
						break;

					case DownloadQueue::eaHistoryProcess:
						HistoryProcess(downloadQueue, itHistory, historyInfo);
						break;

					case DownloadQueue::eaHistoryRedownload:
						HistoryRedownload(downloadQueue, itHistory, historyInfo, false);
						break;

					case DownloadQueue::eaHistoryRetryFailed:
						HistoryRetry(downloadQueue, itHistory, historyInfo, true, false);
						break;

					case DownloadQueue::eaHistorySetParameter:
						ok = HistorySetParameter(historyInfo, text);
						break;

 					case DownloadQueue::eaHistorySetCategory:
						ok = HistorySetCategory(historyInfo, text);
						break;

 					case DownloadQueue::eaHistorySetName:
						ok = HistorySetName(historyInfo, text);
						break;

					case DownloadQueue::eaHistorySetDupeKey:
					case DownloadQueue::eaHistorySetDupeScore:
					case DownloadQueue::eaHistorySetDupeMode:
					case DownloadQueue::eaHistorySetDupeBackup:
						HistorySetDupeParam(historyInfo, action, text);
						break;

					case DownloadQueue::eaHistoryMarkBad:
						g_DupeCoordinator->HistoryMark(downloadQueue, historyInfo, NzbInfo::ksBad);
						break;

					case DownloadQueue::eaHistoryMarkGood:
						g_DupeCoordinator->HistoryMark(downloadQueue, historyInfo, NzbInfo::ksGood);
						break;

					case DownloadQueue::eaHistoryMarkSuccess:
						g_DupeCoordinator->HistoryMark(downloadQueue, historyInfo, NzbInfo::ksSuccess);
						break;

					default:
						// nothing, just to avoid compiler warning
						break;
				}

				break;
			}
		}
	}

	if (ok)
	{
		downloadQueue->HistoryChanged();
		downloadQueue->Save();
	}

	return ok;
}