mirror of
https://github.com/nzbget/nzbget.git
synced 2026-01-26 06:47:44 -05:00
replaced parameter "NoDupeCheck (yes, no)" with "DupeMode (score, all, force)" when adding nzb-files to queue using RPC-methods "append" and "appendurl"; changed option "nodupe" to "dupemode" in RSS filter commands "Append" and "Options"
This commit is contained in:
@@ -70,10 +70,10 @@ PrePostProcessor::PrePostProcessor()
|
||||
|
||||
m_QueueCoordinatorObserver.m_pOwner = this;
|
||||
g_pQueueCoordinator->Attach(&m_QueueCoordinatorObserver);
|
||||
|
||||
#ifndef DISABLE_PARCHECK
|
||||
m_ParCoordinator.m_pOwner = this;
|
||||
#endif
|
||||
m_DupeCoordinator.m_pOwner = this;
|
||||
}
|
||||
|
||||
PrePostProcessor::~PrePostProcessor()
|
||||
@@ -247,9 +247,9 @@ void PrePostProcessor::QueueCoordinatorUpdate(Subject * Caller, void * Aspect)
|
||||
|
||||
void PrePostProcessor::NZBFound(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo)
|
||||
{
|
||||
if (g_pOptions->GetDupeCheck() && !pNZBInfo->GetNoDupeCheck())
|
||||
if (g_pOptions->GetDupeCheck() && pNZBInfo->GetDupeMode() != dmForce)
|
||||
{
|
||||
CheckDupeFound(pDownloadQueue, pNZBInfo);
|
||||
m_DupeCoordinator.NZBFound(pDownloadQueue, pNZBInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,9 +260,16 @@ void PrePostProcessor::NZBAdded(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo
|
||||
m_ParCoordinator.PausePars(pDownloadQueue, pNZBInfo);
|
||||
}
|
||||
|
||||
if (g_pOptions->GetDupeCheck() && !pNZBInfo->GetNoDupeCheck())
|
||||
if (g_pOptions->GetDupeCheck() && pNZBInfo->GetDupeMode() != dmForce)
|
||||
{
|
||||
CheckDupeAdded(pDownloadQueue, pNZBInfo);
|
||||
if (pNZBInfo->GetDeleteStatus() == NZBInfo::dsDupe)
|
||||
{
|
||||
NZBCompleted(pDownloadQueue, pNZBInfo, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_DupeCoordinator.NZBAdded(pDownloadQueue, pNZBInfo);
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(g_pOptions->GetNZBAddedProcess()) > 0)
|
||||
@@ -413,11 +420,11 @@ void PrePostProcessor::NZBCompleted(DownloadQueue* pDownloadQueue, NZBInfo* pNZB
|
||||
bNeedSave = true;
|
||||
}
|
||||
|
||||
if (pNZBInfo->GetDupe() &&
|
||||
if (g_pOptions->GetDupeCheck() && pNZBInfo->GetDupeMode() != dmForce &&
|
||||
(pNZBInfo->GetDeleteStatus() == NZBInfo::dsNone ||
|
||||
pNZBInfo->GetDeleteStatus() == NZBInfo::dsHealth))
|
||||
{
|
||||
DupeCompleted(pDownloadQueue, pNZBInfo);
|
||||
m_DupeCoordinator.NZBCompleted(pDownloadQueue, pNZBInfo);
|
||||
bNeedSave = true;
|
||||
}
|
||||
|
||||
@@ -427,384 +434,14 @@ void PrePostProcessor::NZBCompleted(DownloadQueue* pDownloadQueue, NZBInfo* pNZB
|
||||
}
|
||||
}
|
||||
|
||||
bool PrePostProcessor::IsDupeSuccess(NZBInfo* pNZBInfo)
|
||||
{
|
||||
bool bFailure =
|
||||
pNZBInfo->GetDeleteStatus() != NZBInfo::dsNone ||
|
||||
pNZBInfo->GetMarkStatus() == NZBInfo::ksBad ||
|
||||
pNZBInfo->GetParStatus() == NZBInfo::psFailure ||
|
||||
pNZBInfo->GetUnpackStatus() == NZBInfo::usFailure ||
|
||||
(pNZBInfo->GetParStatus() == NZBInfo::psSkipped &&
|
||||
pNZBInfo->GetUnpackStatus() == NZBInfo::usSkipped &&
|
||||
pNZBInfo->CalcHealth() < pNZBInfo->CalcCriticalHealth());
|
||||
return !bFailure;
|
||||
}
|
||||
|
||||
/**
|
||||
- if download of an item completes successfully and there are
|
||||
(paused) duplicates to this item in the queue, they all are deleted
|
||||
from queue;
|
||||
- if download of an item fails and there are (paused) duplicates to
|
||||
this item in the queue iten with highest DupeScore is unpaused;
|
||||
*/
|
||||
void PrePostProcessor::DupeCompleted(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo)
|
||||
* Removes old entries from (recent) history
|
||||
*/
|
||||
void PrePostProcessor::CheckHistory()
|
||||
{
|
||||
debug("Processing duplicates for %s", pNZBInfo->GetName());
|
||||
DownloadQueue* pDownloadQueue = g_pQueueCoordinator->LockQueue();
|
||||
|
||||
if (IsDupeSuccess(pNZBInfo))
|
||||
{
|
||||
RemoveDupes(pDownloadQueue, pNZBInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnpauseBestDupe(pDownloadQueue, pNZBInfo, pNZBInfo->GetName(), pNZBInfo->GetDupeKey());
|
||||
}
|
||||
}
|
||||
|
||||
void PrePostProcessor::RemoveDupes(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo)
|
||||
{
|
||||
bool bHasDupeKey = !Util::EmptyStr(pNZBInfo->GetDupeKey());
|
||||
IDList groupIDList;
|
||||
std::set<NZBInfo*> groupNZBs;
|
||||
|
||||
for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++)
|
||||
{
|
||||
FileInfo* pFileInfo = *it;
|
||||
if (pFileInfo->GetNZBInfo() != pNZBInfo &&
|
||||
pFileInfo->GetNZBInfo()->GetDupe() &&
|
||||
groupNZBs.find(pFileInfo->GetNZBInfo()) == groupNZBs.end() &&
|
||||
(!strcmp(pFileInfo->GetNZBInfo()->GetName(), pNZBInfo->GetName()) ||
|
||||
(bHasDupeKey && !strcmp(pFileInfo->GetNZBInfo()->GetDupeKey(), pNZBInfo->GetDupeKey()))))
|
||||
{
|
||||
groupIDList.push_back(pFileInfo->GetID());
|
||||
groupNZBs.insert(pFileInfo->GetNZBInfo());
|
||||
pFileInfo->GetNZBInfo()->SetDeleteStatus(NZBInfo::dsDupe);
|
||||
}
|
||||
}
|
||||
|
||||
if (!groupIDList.empty())
|
||||
{
|
||||
info("Removing duplicates for %s from queue", pNZBInfo->GetName());
|
||||
g_pQueueCoordinator->GetQueueEditor()->LockedEditList(pDownloadQueue, &groupIDList, false, QueueEditor::eaGroupDelete, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void PrePostProcessor::UnpauseBestDupe(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo, const char* szNZBName, const char* szDupeKey)
|
||||
{
|
||||
bool bHasDupeKey = !Util::EmptyStr(szDupeKey);
|
||||
std::set<NZBInfo*> groupNZBs;
|
||||
FileInfo* pDupeFileInfo = NULL;
|
||||
|
||||
for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++)
|
||||
{
|
||||
FileInfo* pFileInfo = *it;
|
||||
if (pFileInfo->GetNZBInfo() != pNZBInfo &&
|
||||
pFileInfo->GetNZBInfo()->GetDupe() &&
|
||||
groupNZBs.find(pFileInfo->GetNZBInfo()) == groupNZBs.end() &&
|
||||
(!strcmp(pFileInfo->GetNZBInfo()->GetName(), szNZBName) ||
|
||||
(bHasDupeKey && !strcmp(pFileInfo->GetNZBInfo()->GetDupeKey(), szDupeKey))))
|
||||
{
|
||||
// find nzb with highest DupeScore
|
||||
if (!pDupeFileInfo || pFileInfo->GetNZBInfo()->GetDupeScore() > pDupeFileInfo->GetNZBInfo()->GetDupeScore())
|
||||
{
|
||||
pDupeFileInfo = pFileInfo;
|
||||
}
|
||||
groupNZBs.insert(pFileInfo->GetNZBInfo());
|
||||
}
|
||||
}
|
||||
|
||||
if (pDupeFileInfo)
|
||||
{
|
||||
info("Unpausing duplicate %s", pDupeFileInfo->GetNZBInfo()->GetName());
|
||||
g_pQueueCoordinator->GetQueueEditor()->LockedEditEntry(pDownloadQueue, pDupeFileInfo->GetID(), false, QueueEditor::eaGroupResume, 0, NULL);
|
||||
g_pQueueCoordinator->GetQueueEditor()->LockedEditEntry(pDownloadQueue, pDupeFileInfo->GetID(), false, QueueEditor::eaGroupPauseExtraPars, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Check if the title was already downloaded or is already queued.
|
||||
*/
|
||||
void PrePostProcessor::CheckDupeFound(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo)
|
||||
{
|
||||
debug("Checking duplicates for %s", pNZBInfo->GetName());
|
||||
|
||||
bool bHasDupeKey = !Util::EmptyStr(pNZBInfo->GetDupeKey());
|
||||
|
||||
// find duplicates in download queue having exactly same content
|
||||
GroupQueue groupQueue;
|
||||
pDownloadQueue->BuildGroups(&groupQueue);
|
||||
|
||||
for (GroupQueue::iterator it = groupQueue.begin(); it != groupQueue.end(); it++)
|
||||
{
|
||||
GroupInfo* pGroupInfo = *it;
|
||||
NZBInfo* pGroupNZBInfo = pGroupInfo->GetNZBInfo();
|
||||
bool bSameContent = (pNZBInfo->GetFullContentHash() > 0 &&
|
||||
pNZBInfo->GetFullContentHash() == pGroupNZBInfo->GetFullContentHash()) ||
|
||||
(pNZBInfo->GetFilteredContentHash() > 0 &&
|
||||
pNZBInfo->GetFilteredContentHash() == pGroupNZBInfo->GetFilteredContentHash());
|
||||
if (pGroupNZBInfo != pNZBInfo && bSameContent)
|
||||
{
|
||||
if (!strcmp(pNZBInfo->GetName(), pGroupNZBInfo->GetName()))
|
||||
{
|
||||
warn("Skipping duplicate %s, already queued", pNZBInfo->GetName());
|
||||
}
|
||||
else
|
||||
{
|
||||
warn("Skipping duplicate %s, already queued as %s",
|
||||
pNZBInfo->GetName(), pGroupNZBInfo->GetName());
|
||||
}
|
||||
pNZBInfo->SetDeleteStatus(NZBInfo::dsManual); // Flag saying QueueCoordinator to skip nzb-file
|
||||
DeleteQueuedFile(pNZBInfo->GetQueuedFilename());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// find duplicates in post queue having exactly same content
|
||||
for (PostQueue::iterator it = pDownloadQueue->GetPostQueue()->begin(); it != pDownloadQueue->GetPostQueue()->end(); it++)
|
||||
{
|
||||
PostInfo* pPostInfo = *it;
|
||||
bool bSameContent = (pNZBInfo->GetFullContentHash() > 0 &&
|
||||
pNZBInfo->GetFullContentHash() == pPostInfo->GetNZBInfo()->GetFullContentHash()) ||
|
||||
(pNZBInfo->GetFilteredContentHash() > 0 &&
|
||||
pNZBInfo->GetFilteredContentHash() == pPostInfo->GetNZBInfo()->GetFilteredContentHash());
|
||||
if (bSameContent)
|
||||
{
|
||||
if (!strcmp(pNZBInfo->GetName(), pPostInfo->GetNZBInfo()->GetName()))
|
||||
{
|
||||
warn("Skipping duplicate %s, already queued", pNZBInfo->GetName());
|
||||
}
|
||||
else
|
||||
{
|
||||
warn("Skipping duplicate %s, already queued as %s",
|
||||
pNZBInfo->GetName(), pPostInfo->GetNZBInfo()->GetName());
|
||||
}
|
||||
pNZBInfo->SetDeleteStatus(NZBInfo::dsManual); // Flag saying QueueCoordinator to skip nzb-file
|
||||
DeleteQueuedFile(pNZBInfo->GetQueuedFilename());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// find duplicates in history
|
||||
|
||||
bool bSkip = false;
|
||||
bool bGood = false;
|
||||
bool bSameContent = false;
|
||||
const char* szDupeName = NULL;
|
||||
|
||||
// find duplicates in queue having exactly same content
|
||||
// also: nzb-files having duplicates marked as good are skipped
|
||||
// also: nzb-files having success-duplicates in dup-history but don't having duplicates in recent history are skipped
|
||||
for (HistoryList::iterator it = pDownloadQueue->GetHistoryList()->begin(); it != pDownloadQueue->GetHistoryList()->end(); it++)
|
||||
{
|
||||
HistoryInfo* pHistoryInfo = *it;
|
||||
|
||||
if (pHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo &&
|
||||
((pNZBInfo->GetFullContentHash() > 0 &&
|
||||
pNZBInfo->GetFullContentHash() == pHistoryInfo->GetNZBInfo()->GetFullContentHash()) ||
|
||||
(pNZBInfo->GetFilteredContentHash() > 0 &&
|
||||
pNZBInfo->GetFilteredContentHash() == pHistoryInfo->GetNZBInfo()->GetFilteredContentHash())))
|
||||
{
|
||||
bSkip = true;
|
||||
bSameContent = true;
|
||||
szDupeName = pHistoryInfo->GetNZBInfo()->GetName();
|
||||
break;
|
||||
}
|
||||
|
||||
if (pHistoryInfo->GetKind() == HistoryInfo::hkDupInfo &&
|
||||
((pNZBInfo->GetFullContentHash() > 0 &&
|
||||
pNZBInfo->GetFullContentHash() == pHistoryInfo->GetDupInfo()->GetFullContentHash()) ||
|
||||
(pNZBInfo->GetFilteredContentHash() > 0 &&
|
||||
pNZBInfo->GetFilteredContentHash() == pHistoryInfo->GetDupInfo()->GetFilteredContentHash())))
|
||||
{
|
||||
bSkip = true;
|
||||
bSameContent = true;
|
||||
szDupeName = pHistoryInfo->GetDupInfo()->GetName();
|
||||
break;
|
||||
}
|
||||
|
||||
if (pHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo &&
|
||||
pHistoryInfo->GetNZBInfo()->GetMarkStatus() == NZBInfo::ksGood &&
|
||||
(!strcmp(pHistoryInfo->GetNZBInfo()->GetName(), pNZBInfo->GetName()) ||
|
||||
(bHasDupeKey && !strcmp(pHistoryInfo->GetNZBInfo()->GetDupeKey(), pNZBInfo->GetDupeKey()))))
|
||||
{
|
||||
bSkip = true;
|
||||
bGood = true;
|
||||
szDupeName = pHistoryInfo->GetNZBInfo()->GetName();
|
||||
break;
|
||||
}
|
||||
|
||||
if (pHistoryInfo->GetKind() == HistoryInfo::hkDupInfo &&
|
||||
(!strcmp(pHistoryInfo->GetDupInfo()->GetName(), pNZBInfo->GetName()) ||
|
||||
(bHasDupeKey && !strcmp(pHistoryInfo->GetDupInfo()->GetDupeKey(), pNZBInfo->GetDupeKey()))) &&
|
||||
(pHistoryInfo->GetDupInfo()->GetStatus() == DupInfo::dsGood ||
|
||||
(pHistoryInfo->GetDupInfo()->GetStatus() == DupInfo::dsSuccess &&
|
||||
pNZBInfo->GetDupeScore() <= pHistoryInfo->GetDupInfo()->GetDupeScore())))
|
||||
{
|
||||
bSkip = true;
|
||||
bGood = pHistoryInfo->GetDupInfo()->GetStatus() == DupInfo::dsGood;
|
||||
szDupeName = pHistoryInfo->GetDupInfo()->GetName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bSameContent && !bGood)
|
||||
{
|
||||
// nzb-files having success-duplicates in recent history (with different content) are added to history for backup
|
||||
for (HistoryList::iterator it = pDownloadQueue->GetHistoryList()->begin(); it != pDownloadQueue->GetHistoryList()->end(); it++)
|
||||
{
|
||||
HistoryInfo* pHistoryInfo = *it;
|
||||
if (pHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo &&
|
||||
(!strcmp(pHistoryInfo->GetNZBInfo()->GetName(), pNZBInfo->GetName()) ||
|
||||
(bHasDupeKey && !strcmp(pHistoryInfo->GetNZBInfo()->GetDupeKey(), pNZBInfo->GetDupeKey()))) &&
|
||||
pNZBInfo->GetDupeScore() <= pHistoryInfo->GetNZBInfo()->GetDupeScore() &&
|
||||
IsDupeSuccess(pHistoryInfo->GetNZBInfo()))
|
||||
{
|
||||
// Flag saying QueueCoordinator to skip nzb-file, we also use this flag later in "CheckDupeAdded"
|
||||
pNZBInfo->SetDeleteStatus(NZBInfo::dsDupe);
|
||||
MarkDupe(pNZBInfo, pHistoryInfo->GetNZBInfo());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bSkip)
|
||||
{
|
||||
if (!strcmp(pNZBInfo->GetName(), szDupeName))
|
||||
{
|
||||
warn("Skipping duplicate %s, found in history with %s", pNZBInfo->GetName(),
|
||||
bSameContent ? "exactly same content" : bGood ? "good status" : "success status");
|
||||
}
|
||||
else
|
||||
{
|
||||
warn("Skipping duplicate %s, found in history %s with %s",
|
||||
pNZBInfo->GetName(), szDupeName,
|
||||
bSameContent ? "exactly same content" : bGood ? "good status" : "success status");
|
||||
}
|
||||
|
||||
// Flag saying QueueCoordinator to skip nzb-file
|
||||
pNZBInfo->SetDeleteStatus(NZBInfo::dsManual);
|
||||
DeleteQueuedFile(pNZBInfo->GetQueuedFilename());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
- If download queue or post-queue contain a duplicate the existing item
|
||||
and the newly added item are marked as duplicates to each other.
|
||||
The newly added item is paused.
|
||||
*/
|
||||
void PrePostProcessor::CheckDupeAdded(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo)
|
||||
{
|
||||
debug("Checking duplicates for %s", pNZBInfo->GetName());
|
||||
|
||||
if (pNZBInfo->GetDeleteStatus() == NZBInfo::dsDupe)
|
||||
{
|
||||
NZBCompleted(pDownloadQueue, pNZBInfo, false);
|
||||
return;
|
||||
}
|
||||
|
||||
bool bHasDupeKey = !Util::EmptyStr(pNZBInfo->GetDupeKey());
|
||||
bool bHigherScore = true;
|
||||
NZBInfo* pDupeNZBInfo = NULL;
|
||||
|
||||
// find all duplicates in post queue
|
||||
std::set<NZBInfo*> postDupes;
|
||||
|
||||
for (PostQueue::iterator it = pDownloadQueue->GetPostQueue()->begin(); it != pDownloadQueue->GetPostQueue()->end(); it++)
|
||||
{
|
||||
PostInfo* pPostInfo = *it;
|
||||
if (!strcmp(pPostInfo->GetNZBInfo()->GetName(), pNZBInfo->GetName()) ||
|
||||
(bHasDupeKey && !strcmp(pPostInfo->GetNZBInfo()->GetDupeKey(), pNZBInfo->GetDupeKey())))
|
||||
{
|
||||
postDupes.insert(pPostInfo->GetNZBInfo());
|
||||
if (!pDupeNZBInfo)
|
||||
{
|
||||
pDupeNZBInfo = pPostInfo->GetNZBInfo();
|
||||
}
|
||||
bHigherScore = bHigherScore && pPostInfo->GetNZBInfo()->GetDupeScore() < pNZBInfo->GetDupeScore();
|
||||
}
|
||||
}
|
||||
|
||||
// find all duplicates in download queue
|
||||
GroupQueue groupQueue;
|
||||
pDownloadQueue->BuildGroups(&groupQueue);
|
||||
std::list<GroupInfo*> queueDupes;
|
||||
GroupInfo* pNewGroupInfo = NULL;
|
||||
|
||||
for (GroupQueue::iterator it = groupQueue.begin(); it != groupQueue.end(); it++)
|
||||
{
|
||||
GroupInfo* pGroupInfo = *it;
|
||||
NZBInfo* pGroupNZBInfo = pGroupInfo->GetNZBInfo();
|
||||
if (pGroupNZBInfo != pNZBInfo &&
|
||||
(!strcmp(pGroupNZBInfo->GetName(), pNZBInfo->GetName()) ||
|
||||
(bHasDupeKey && !strcmp(pGroupNZBInfo->GetDupeKey(), pNZBInfo->GetDupeKey()))))
|
||||
{
|
||||
queueDupes.push_back(pGroupInfo);
|
||||
if (!pDupeNZBInfo)
|
||||
{
|
||||
pDupeNZBInfo = pGroupNZBInfo;
|
||||
}
|
||||
bHigherScore = bHigherScore && pGroupNZBInfo->GetDupeScore() < pNZBInfo->GetDupeScore();
|
||||
}
|
||||
if (pGroupNZBInfo == pNZBInfo)
|
||||
{
|
||||
pNewGroupInfo = pGroupInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (pDupeNZBInfo)
|
||||
{
|
||||
MarkDupe(pNZBInfo, pDupeNZBInfo);
|
||||
|
||||
// pause all duplicates with lower DupeScore, which are not in post-processing
|
||||
for (std::list<GroupInfo*>::iterator it = queueDupes.begin(); it != queueDupes.end(); it++)
|
||||
{
|
||||
GroupInfo* pGroupInfo = *it;
|
||||
NZBInfo* pDupeNZB = pGroupInfo->GetNZBInfo();
|
||||
if (pDupeNZB->GetDupeScore() < pNZBInfo->GetDupeScore() &&
|
||||
postDupes.find(pDupeNZB) == postDupes.end() &&
|
||||
pGroupInfo->GetPausedFileCount() < pGroupInfo->GetRemainingFileCount())
|
||||
{
|
||||
info("Pausing collection %s with lower duplicate score", pDupeNZB->GetName());
|
||||
g_pQueueCoordinator->GetQueueEditor()->LockedEditEntry(pDownloadQueue, pGroupInfo->GetLastID(), false, QueueEditor::eaGroupPause, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!bHigherScore)
|
||||
{
|
||||
g_pQueueCoordinator->GetQueueEditor()->LockedEditEntry(pDownloadQueue, pNewGroupInfo->GetLastID(), false, QueueEditor::eaGroupPause, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PrePostProcessor::MarkDupe(NZBInfo* pNZBInfo, NZBInfo* pDupeNZBInfo)
|
||||
{
|
||||
info("Marking collection %s as duplicate to %s", pNZBInfo->GetName(), pDupeNZBInfo->GetName());
|
||||
|
||||
pNZBInfo->SetDupe(true);
|
||||
pDupeNZBInfo->SetDupe(true);
|
||||
|
||||
if (Util::EmptyStr(pNZBInfo->GetDupeKey()) && !Util::EmptyStr(pDupeNZBInfo->GetDupeKey()))
|
||||
{
|
||||
pNZBInfo->SetDupeKey(pDupeNZBInfo->GetDupeKey());
|
||||
}
|
||||
}
|
||||
|
||||
void PrePostProcessor::CleanupHistory(DownloadQueue* pDownloadQueue, EHistoryCleanupMode eMode, HistoryInfo* pMarkHistoryInfo)
|
||||
{
|
||||
time_t tMinTime = time(NULL) - g_pOptions->GetKeepHistory() * 60*60*24;
|
||||
const char* szDupeKey = NULL;
|
||||
const char* szNZBName = NULL;
|
||||
if (eMode == cmDupe)
|
||||
{
|
||||
szDupeKey = pMarkHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo ? pMarkHistoryInfo->GetNZBInfo()->GetDupeKey() :
|
||||
pMarkHistoryInfo->GetKind() == HistoryInfo::hkDupInfo ? pMarkHistoryInfo->GetDupInfo()->GetDupeKey() :
|
||||
NULL;
|
||||
szNZBName = pMarkHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo ? pMarkHistoryInfo->GetNZBInfo()->GetName() :
|
||||
pMarkHistoryInfo->GetKind() == HistoryInfo::hkDupInfo ? pMarkHistoryInfo->GetDupInfo()->GetName() :
|
||||
NULL;
|
||||
}
|
||||
bool bHasDupeKey = !Util::EmptyStr(szDupeKey);
|
||||
bool bChanged = false;
|
||||
int index = 0;
|
||||
|
||||
@@ -813,54 +450,29 @@ void PrePostProcessor::CleanupHistory(DownloadQueue* pDownloadQueue, EHistoryCle
|
||||
for (HistoryList::reverse_iterator it = pDownloadQueue->GetHistoryList()->rbegin(); it != pDownloadQueue->GetHistoryList()->rend(); )
|
||||
{
|
||||
HistoryInfo* pHistoryInfo = *it;
|
||||
if ((eMode == cmOld && pHistoryInfo->GetKind() != HistoryInfo::hkDupInfo && pHistoryInfo->GetTime() < tMinTime)
|
||||
||
|
||||
(eMode == cmDupe && pHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo &&
|
||||
pHistoryInfo != pMarkHistoryInfo && pHistoryInfo->GetNZBInfo()->GetDupe() &&
|
||||
(!strcmp(pHistoryInfo->GetNZBInfo()->GetName(), szNZBName) ||
|
||||
(bHasDupeKey && !strcmp(pHistoryInfo->GetNZBInfo()->GetDupeKey(), szDupeKey)))))
|
||||
if (pHistoryInfo->GetKind() != HistoryInfo::hkDupInfo && pHistoryInfo->GetTime() < tMinTime)
|
||||
{
|
||||
char szNiceName[1024];
|
||||
pHistoryInfo->GetName(szNiceName, 1024);
|
||||
|
||||
if (g_pOptions->GetDupeCheck() && pHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo)
|
||||
{
|
||||
// replace history element
|
||||
DupInfo* pDupInfo = new DupInfo();
|
||||
pDupInfo->SetName(pHistoryInfo->GetNZBInfo()->GetName());
|
||||
pDupInfo->SetDupe(pHistoryInfo->GetNZBInfo()->GetDupe());
|
||||
pDupInfo->SetDupeKey(pHistoryInfo->GetNZBInfo()->GetDupeKey());
|
||||
pDupInfo->SetDupeScore(pHistoryInfo->GetNZBInfo()->GetDupeScore());
|
||||
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()->GetDeleteStatus() == NZBInfo::dsDupe ? DupInfo::dsDupe :
|
||||
pHistoryInfo->GetNZBInfo()->GetDeleteStatus() == NZBInfo::dsManual ? DupInfo::dsDeleted :
|
||||
IsDupeSuccess(pHistoryInfo->GetNZBInfo()) ? DupInfo::dsSuccess :
|
||||
DupInfo::dsFailed);
|
||||
|
||||
HistoryInfo* pNewHistoryInfo = new HistoryInfo(pDupInfo);
|
||||
pNewHistoryInfo->SetTime(pHistoryInfo->GetTime());
|
||||
(*pDownloadQueue->GetHistoryList())[pDownloadQueue->GetHistoryList()->size() - 1 - index] = pNewHistoryInfo;
|
||||
info("Collection %s removed from recent history", szNiceName);
|
||||
m_DupeCoordinator.HistoryTransformToDup(pDownloadQueue, pHistoryInfo, index);
|
||||
index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
char szNiceName[1024];
|
||||
pHistoryInfo->GetName(szNiceName, 1024);
|
||||
|
||||
pDownloadQueue->GetHistoryList()->erase(pDownloadQueue->GetHistoryList()->end() - 1 - index);
|
||||
delete pHistoryInfo;
|
||||
|
||||
if (pHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo)
|
||||
{
|
||||
DeleteQueuedFile(pHistoryInfo->GetNZBInfo()->GetQueuedFilename());
|
||||
}
|
||||
info("Collection %s removed from history", szNiceName);
|
||||
}
|
||||
|
||||
if (pHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo)
|
||||
{
|
||||
DeleteQueuedFile(pHistoryInfo->GetNZBInfo()->GetQueuedFilename());
|
||||
}
|
||||
|
||||
delete pHistoryInfo;
|
||||
it = pDownloadQueue->GetHistoryList()->rbegin() + index;
|
||||
bChanged = true;
|
||||
}
|
||||
@@ -875,15 +487,7 @@ void PrePostProcessor::CleanupHistory(DownloadQueue* pDownloadQueue, EHistoryCle
|
||||
{
|
||||
SaveQueue(pDownloadQueue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes old entries from (recent) history
|
||||
*/
|
||||
void PrePostProcessor::CheckHistory()
|
||||
{
|
||||
DownloadQueue* pDownloadQueue = g_pQueueCoordinator->LockQueue();
|
||||
CleanupHistory(pDownloadQueue, cmOld, NULL);
|
||||
g_pQueueCoordinator->UnlockQueue();
|
||||
}
|
||||
|
||||
@@ -1540,7 +1144,7 @@ bool PrePostProcessor::HistoryEdit(IDList* pIDList, EEditAction eAction, int iOf
|
||||
|
||||
case eaHistoryMarkBad:
|
||||
case eaHistoryMarkGood:
|
||||
HistoryMark(pDownloadQueue, pHistoryInfo, eAction == eaHistoryMarkGood);
|
||||
m_DupeCoordinator.HistoryMark(pDownloadQueue, pHistoryInfo, eAction == eaHistoryMarkGood);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1720,104 +1324,3 @@ void PrePostProcessor::HistorySetParameter(HistoryInfo* pHistoryInfo, const char
|
||||
|
||||
free(szStr);
|
||||
}
|
||||
|
||||
void PrePostProcessor::HistoryMark(DownloadQueue* pDownloadQueue, HistoryInfo* pHistoryInfo, bool bGood)
|
||||
{
|
||||
char szNZBName[1024];
|
||||
pHistoryInfo->GetName(szNZBName, 1024);
|
||||
|
||||
info("Marking %s as %s", szNZBName, (bGood ? "good" : "bad"));
|
||||
|
||||
if (pHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo)
|
||||
{
|
||||
pHistoryInfo->GetNZBInfo()->SetMarkStatus(bGood ? NZBInfo::ksGood : NZBInfo::ksBad);
|
||||
}
|
||||
else if (pHistoryInfo->GetKind() == HistoryInfo::hkDupInfo)
|
||||
{
|
||||
pHistoryInfo->GetDupInfo()->SetStatus(bGood ? DupInfo::dsGood : DupInfo::dsBad);
|
||||
}
|
||||
else
|
||||
{
|
||||
error("Could not mark %s as bad: history item has wrong type", szNZBName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_pOptions->GetDupeCheck())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (bGood)
|
||||
{
|
||||
// mark as good
|
||||
// moving all duplicates from history to dup-history
|
||||
CleanupHistory(pDownloadQueue, cmDupe, pHistoryInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
// mark as bad continues
|
||||
|
||||
const char* szDupeKey = pHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo ? pHistoryInfo->GetNZBInfo()->GetDupeKey() :
|
||||
pHistoryInfo->GetKind() == HistoryInfo::hkDupInfo ? pHistoryInfo->GetDupInfo()->GetDupeKey() :
|
||||
NULL;
|
||||
bool bHasDupeKey = !Util::EmptyStr(szDupeKey);
|
||||
|
||||
// move existing dupe-backups from history to download queue
|
||||
HistoryList dupeList;
|
||||
for (HistoryList::iterator it = pDownloadQueue->GetHistoryList()->begin(); it != pDownloadQueue->GetHistoryList()->end(); it++)
|
||||
{
|
||||
HistoryInfo* pDupeHistoryInfo = *it;
|
||||
if (pDupeHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo &&
|
||||
pDupeHistoryInfo->GetNZBInfo()->GetDupe() &&
|
||||
pDupeHistoryInfo->GetNZBInfo()->GetDeleteStatus() == NZBInfo::dsDupe &&
|
||||
(!strcmp(pDupeHistoryInfo->GetNZBInfo()->GetName(), szNZBName) ||
|
||||
(bHasDupeKey && !strcmp(pDupeHistoryInfo->GetNZBInfo()->GetDupeKey(), szDupeKey))))
|
||||
{
|
||||
dupeList.push_back(pDupeHistoryInfo);
|
||||
}
|
||||
}
|
||||
|
||||
for (HistoryList::iterator it = dupeList.begin(); it != dupeList.end(); it++)
|
||||
{
|
||||
HistoryInfo* pDupeHistoryInfo = *it;
|
||||
HistoryReturnDupe(pDownloadQueue, pDupeHistoryInfo);
|
||||
}
|
||||
|
||||
UnpauseBestDupe(pDownloadQueue, NULL, szNZBName, szDupeKey);
|
||||
}
|
||||
|
||||
void PrePostProcessor::HistoryReturnDupe(DownloadQueue* pDownloadQueue, HistoryInfo* pHistoryInfo)
|
||||
{
|
||||
NZBInfo* pNZBInfo = pHistoryInfo->GetNZBInfo();
|
||||
|
||||
if (!Util::FileExists(pNZBInfo->GetQueuedFilename()))
|
||||
{
|
||||
error("Could not return duplicate %s from history back to queue: could not find source nzb-file %s",
|
||||
pNZBInfo->GetName(), pNZBInfo->GetQueuedFilename());
|
||||
return;
|
||||
}
|
||||
|
||||
NZBFile* pNZBFile = NZBFile::Create(pNZBInfo->GetQueuedFilename(), "");
|
||||
if (pNZBFile == NULL)
|
||||
{
|
||||
error("Could not return duplicate %s from history back to queue: could not parse nzb-file",
|
||||
pNZBInfo->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
info("Returning duplicate %s from history back to queue", pNZBInfo->GetName());
|
||||
|
||||
for (NZBFile::FileInfos::iterator it = pNZBFile->GetFileInfos()->begin(); it != pNZBFile->GetFileInfos()->end(); it++)
|
||||
{
|
||||
FileInfo* pFileInfo = *it;
|
||||
pFileInfo->SetNZBInfo(pNZBInfo);
|
||||
pFileInfo->SetPaused(true);
|
||||
}
|
||||
|
||||
g_pQueueCoordinator->AddFileInfosToFileQueue(pNZBFile, pDownloadQueue->GetParkedFiles(), false);
|
||||
|
||||
delete pNZBFile;
|
||||
|
||||
HistoryList::iterator it = std::find(pDownloadQueue->GetHistoryList()->begin(), pDownloadQueue->GetHistoryList()->end(), pHistoryInfo);
|
||||
HistoryReturn(pDownloadQueue, it, pHistoryInfo, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user