ParChecker::EFileStatus ParCoordinator::PostParChecker::FindFileCrc(const char* szFilename, unsigned long* lCrc, SegmentList* pSegments) { CompletedFile* pCompletedFile = NULL; for (CompletedFiles::iterator it = m_pPostInfo->GetNZBInfo()->GetCompletedFiles()->begin(); it != m_pPostInfo->GetNZBInfo()->GetCompletedFiles()->end(); it++) { CompletedFile* pCompletedFile2 = *it; if (!strcasecmp(pCompletedFile2->GetFileName(), szFilename)) { pCompletedFile = pCompletedFile2; break; } } if (!pCompletedFile) { return ParChecker::fsUnknown; } debug("Found completed file: %s, CRC: %.8x, Status: %i", Util::BaseFileName(pCompletedFile->GetFileName()), pCompletedFile->GetCrc(), (int)pCompletedFile->GetStatus()); *lCrc = pCompletedFile->GetCrc(); if (pCompletedFile->GetStatus() == CompletedFile::cfPartial && pCompletedFile->GetID() > 0 && !m_pPostInfo->GetNZBInfo()->GetReprocess()) { FileInfo* pTmpFileInfo = new FileInfo(pCompletedFile->GetID()); if (!g_pDiskState->LoadFileState(pTmpFileInfo, NULL, true)) { delete pTmpFileInfo; return ParChecker::fsUnknown; } for (FileInfo::Articles::iterator it = pTmpFileInfo->GetArticles()->begin(); it != pTmpFileInfo->GetArticles()->end(); it++) { ArticleInfo* pa = *it; ParChecker::Segment* pSegment = new Segment(pa->GetStatus() == ArticleInfo::aiFinished, pa->GetSegmentOffset(), pa->GetSegmentSize(), pa->GetCrc()); pSegments->push_back(pSegment); } delete pTmpFileInfo; } return pCompletedFile->GetStatus() == CompletedFile::cfSuccess ? ParChecker::fsSuccess : pCompletedFile->GetStatus() == CompletedFile::cfFailure && !m_pPostInfo->GetNZBInfo()->GetReprocess() ? ParChecker::fsFailure : pCompletedFile->GetStatus() == CompletedFile::cfPartial && pSegments->size() > 0 && !m_pPostInfo->GetNZBInfo()->GetReprocess()? ParChecker::fsPartial : ParChecker::fsUnknown; }
void NZBFile::CalcHashes() { TempFileList fileList; for (FileList::iterator it = m_pNZBInfo->GetFileList()->begin(); it != m_pNZBInfo->GetFileList()->end(); it++) { fileList.push_back(*it); } fileList.sort(CompareFileInfo); unsigned int iFullContentHash = 0; unsigned int iFilteredContentHash = 0; int iUseForFilteredCount = 0; for (TempFileList::iterator it = fileList.begin(); it != fileList.end(); it++) { FileInfo* pFileInfo = *it; // check file extension bool bSkip = !pFileInfo->GetParFile() && Util::MatchFileExt(pFileInfo->GetFilename(), g_pOptions->GetExtCleanupDisk(), ",;"); for (FileInfo::Articles::iterator it = pFileInfo->GetArticles()->begin(); it != pFileInfo->GetArticles()->end(); it++) { ArticleInfo* pArticle = *it; int iLen = strlen(pArticle->GetMessageID()); iFullContentHash = Util::HashBJ96(pArticle->GetMessageID(), iLen, iFullContentHash); if (!bSkip) { iFilteredContentHash = Util::HashBJ96(pArticle->GetMessageID(), iLen, iFilteredContentHash); iUseForFilteredCount++; } } } // if filtered hash is based on less than a half of files - do not use filtered hash at all if (iUseForFilteredCount < (int)fileList.size() / 2) { iFilteredContentHash = 0; } m_pNZBInfo->SetFullContentHash(iFullContentHash); m_pNZBInfo->SetFilteredContentHash(iFilteredContentHash); }
void QueueCoordinator::ArticleCompleted(ArticleDownloader* pArticleDownloader) { debug("Article downloaded"); FileInfo* pFileInfo = pArticleDownloader->GetFileInfo(); NZBInfo* pNZBInfo = pFileInfo->GetNZBInfo(); ArticleInfo* pArticleInfo = pArticleDownloader->GetArticleInfo(); bool bRetry = false; bool fileCompleted = false; DownloadQueue* pDownloadQueue = DownloadQueue::Lock(); if (pArticleDownloader->GetStatus() == ArticleDownloader::adFinished) { pArticleInfo->SetStatus(ArticleInfo::aiFinished); pFileInfo->SetSuccessSize(pFileInfo->GetSuccessSize() + pArticleInfo->GetSize()); pNZBInfo->SetCurrentSuccessSize(pNZBInfo->GetCurrentSuccessSize() + pArticleInfo->GetSize()); pNZBInfo->SetParCurrentSuccessSize(pNZBInfo->GetParCurrentSuccessSize() + (pFileInfo->GetParFile() ? pArticleInfo->GetSize() : 0)); pFileInfo->SetSuccessArticles(pFileInfo->GetSuccessArticles() + 1); pNZBInfo->SetCurrentSuccessArticles(pNZBInfo->GetCurrentSuccessArticles() + 1); } else if (pArticleDownloader->GetStatus() == ArticleDownloader::adFailed) { pArticleInfo->SetStatus(ArticleInfo::aiFailed); pFileInfo->SetFailedSize(pFileInfo->GetFailedSize() + pArticleInfo->GetSize()); pNZBInfo->SetCurrentFailedSize(pNZBInfo->GetCurrentFailedSize() + pArticleInfo->GetSize()); pNZBInfo->SetParCurrentFailedSize(pNZBInfo->GetParCurrentFailedSize() + (pFileInfo->GetParFile() ? pArticleInfo->GetSize() : 0)); pFileInfo->SetFailedArticles(pFileInfo->GetFailedArticles() + 1); pNZBInfo->SetCurrentFailedArticles(pNZBInfo->GetCurrentFailedArticles() + 1); } else if (pArticleDownloader->GetStatus() == ArticleDownloader::adRetry) { pArticleInfo->SetStatus(ArticleInfo::aiUndefined); bRetry = true; } if (!bRetry) { pFileInfo->SetRemainingSize(pFileInfo->GetRemainingSize() - pArticleInfo->GetSize()); pNZBInfo->SetRemainingSize(pNZBInfo->GetRemainingSize() - pArticleInfo->GetSize()); if (pFileInfo->GetPaused()) { pNZBInfo->SetPausedSize(pNZBInfo->GetPausedSize() - pArticleInfo->GetSize()); } pFileInfo->SetCompletedArticles(pFileInfo->GetCompletedArticles() + 1); fileCompleted = (int)pFileInfo->GetArticles()->size() == pFileInfo->GetCompletedArticles(); pFileInfo->GetServerStats()->ListOp(pArticleDownloader->GetServerStats(), ServerStatList::soAdd); pNZBInfo->GetCurrentServerStats()->ListOp(pArticleDownloader->GetServerStats(), ServerStatList::soAdd); pFileInfo->SetPartialChanged(true); } if (!pFileInfo->GetFilenameConfirmed() && pArticleDownloader->GetStatus() == ArticleDownloader::adFinished && pArticleDownloader->GetArticleFilename()) { pFileInfo->SetFilename(pArticleDownloader->GetArticleFilename()); pFileInfo->SetFilenameConfirmed(true); if (g_pOptions->GetDupeCheck() && pNZBInfo->GetDupeMode() != dmForce && !pNZBInfo->GetManyDupeFiles() && Util::FileExists(pNZBInfo->GetDestDir(), pFileInfo->GetFilename())) { warn("File \"%s\" seems to be duplicate, cancelling download and deleting file from queue", pFileInfo->GetFilename()); fileCompleted = false; pFileInfo->SetAutoDeleted(true); DeleteQueueEntry(pDownloadQueue, pFileInfo); } } pNZBInfo->SetDownloadedSize(pNZBInfo->GetDownloadedSize() + pArticleDownloader->GetDownloadedSize()); bool deleteFileObj = false; if (fileCompleted && !pFileInfo->GetDeleted()) { // all jobs done DownloadQueue::Unlock(); pArticleDownloader->CompleteFileParts(); pDownloadQueue = DownloadQueue::Lock(); deleteFileObj = true; } CheckHealth(pDownloadQueue, pFileInfo); bool hasOtherDownloaders = false; for (ActiveDownloads::iterator it = m_ActiveDownloads.begin(); it != m_ActiveDownloads.end(); it++) { ArticleDownloader* pDownloader = *it; if (pDownloader != pArticleDownloader && pDownloader->GetFileInfo() == pFileInfo) { hasOtherDownloaders = true; break; } } deleteFileObj |= pFileInfo->GetDeleted() && !hasOtherDownloaders; // remove downloader from downloader list m_ActiveDownloads.erase(std::find(m_ActiveDownloads.begin(), m_ActiveDownloads.end(), pArticleDownloader)); pFileInfo->SetActiveDownloads(pFileInfo->GetActiveDownloads() - 1); pNZBInfo->SetActiveDownloads(pNZBInfo->GetActiveDownloads() - 1); if (deleteFileObj) { DeleteFileInfo(pDownloadQueue, pFileInfo, fileCompleted); pDownloadQueue->Save(); } DownloadQueue::Unlock(); }
void QueueCoordinator::Load() { DownloadQueue* pDownloadQueue = DownloadQueue::Lock(); bool bStatLoaded = true; bool bPerfectServerMatch = true; bool bQueueLoaded = false; if (g_pOptions->GetServerMode() && g_pOptions->GetSaveQueue()) { bStatLoaded = g_pStatMeter->Load(&bPerfectServerMatch); if (g_pOptions->GetReloadQueue() && g_pDiskState->DownloadQueueExists()) { bQueueLoaded = g_pDiskState->LoadDownloadQueue(pDownloadQueue, g_pServerPool->GetServers()); } else { g_pDiskState->DiscardDownloadQueue(); } } if (bQueueLoaded && bStatLoaded) { g_pDiskState->CleanupTempDir(pDownloadQueue); } if (bQueueLoaded && bStatLoaded && !bPerfectServerMatch) { debug("Changes in section <NEWS SERVERS> of config file detected, resaving queue"); // re-save current server list into diskstate to update server ids g_pStatMeter->Save(); // re-save queue into diskstate to update server ids pDownloadQueue->Save(); // re-save file states into diskstate to update server ids if (g_pOptions->GetServerMode() && g_pOptions->GetSaveQueue()) { for (NZBList::iterator it = pDownloadQueue->GetQueue()->begin(); it != pDownloadQueue->GetQueue()->end(); it++) { NZBInfo* pNZBInfo = *it; if (g_pOptions->GetContinuePartial()) { for (FileList::iterator it2 = pNZBInfo->GetFileList()->begin(); it2 != pNZBInfo->GetFileList()->end(); it2++) { FileInfo* pFileInfo = *it2; if (!pFileInfo->GetArticles()->empty()) { g_pDiskState->SaveFileState(pFileInfo, false); } } } for (CompletedFiles::iterator it2 = pNZBInfo->GetCompletedFiles()->begin(); it2 != pNZBInfo->GetCompletedFiles()->end(); it2++) { CompletedFile* pCompletedFile = *it2; if (pCompletedFile->GetStatus() != CompletedFile::cfSuccess && pCompletedFile->GetID() > 0) { FileInfo* pFileInfo = new FileInfo(pCompletedFile->GetID()); if (g_pDiskState->LoadFileState(pFileInfo, g_pServerPool->GetServers(), false)) { g_pDiskState->SaveFileState(pFileInfo, true); } delete pFileInfo; } } } } } CoordinatorDownloadQueue::Loaded(); DownloadQueue::Unlock(); }