예제 #1
0
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;
}
예제 #2
0
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);
}
예제 #3
0
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();
}
예제 #4
0
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();
}