Example #1
0
void QueueCoordinator::StatFileInfo(FileInfo* pFileInfo, bool bCompleted)
{
    NZBInfo* pNZBInfo = pFileInfo->GetNZBInfo();
    if (bCompleted || pNZBInfo->GetDeleting())
    {
        pNZBInfo->SetSuccessSize(pNZBInfo->GetSuccessSize() + pFileInfo->GetSuccessSize());
        pNZBInfo->SetFailedSize(pNZBInfo->GetFailedSize() + pFileInfo->GetFailedSize());
        pNZBInfo->SetFailedArticles(pNZBInfo->GetFailedArticles() + pFileInfo->GetFailedArticles() + pFileInfo->GetMissedArticles());
        pNZBInfo->SetSuccessArticles(pNZBInfo->GetSuccessArticles() + pFileInfo->GetSuccessArticles());
        if (pFileInfo->GetParFile())
        {
            pNZBInfo->SetParSuccessSize(pNZBInfo->GetParSuccessSize() + pFileInfo->GetSuccessSize());
            pNZBInfo->SetParFailedSize(pNZBInfo->GetParFailedSize() + pFileInfo->GetFailedSize());
        }
        pNZBInfo->GetServerStats()->ListOp(pFileInfo->GetServerStats(), ServerStatList::soAdd);
    }
    else if (!pNZBInfo->GetDeleting() && !pNZBInfo->GetParCleanup())
    {
        // file deleted but not the whole nzb and not par-cleanup
        pNZBInfo->SetFileCount(pNZBInfo->GetFileCount() - 1);
        pNZBInfo->SetSize(pNZBInfo->GetSize() - pFileInfo->GetSize());
        pNZBInfo->SetCurrentSuccessSize(pNZBInfo->GetCurrentSuccessSize() - pFileInfo->GetSuccessSize());
        pNZBInfo->SetFailedSize(pNZBInfo->GetFailedSize() - pFileInfo->GetMissedSize());
        pNZBInfo->SetCurrentFailedSize(pNZBInfo->GetCurrentFailedSize() - pFileInfo->GetFailedSize() - pFileInfo->GetMissedSize());
        pNZBInfo->SetTotalArticles(pNZBInfo->GetTotalArticles() - pFileInfo->GetTotalArticles());
        pNZBInfo->SetCurrentSuccessArticles(pNZBInfo->GetCurrentSuccessArticles() - pFileInfo->GetSuccessArticles());
        pNZBInfo->SetCurrentFailedArticles(pNZBInfo->GetCurrentFailedArticles() - pFileInfo->GetFailedArticles());
        pNZBInfo->GetCurrentServerStats()->ListOp(pFileInfo->GetServerStats(), ServerStatList::soSubtract);
        if (pFileInfo->GetParFile())
        {
            pNZBInfo->SetParSize(pNZBInfo->GetParSize() - pFileInfo->GetSize());
            pNZBInfo->SetParCurrentSuccessSize(pNZBInfo->GetParCurrentSuccessSize() - pFileInfo->GetSuccessSize());
            pNZBInfo->SetParFailedSize(pNZBInfo->GetParFailedSize() - pFileInfo->GetMissedSize());
            pNZBInfo->SetParCurrentFailedSize(pNZBInfo->GetParCurrentFailedSize() - pFileInfo->GetFailedSize() - pFileInfo->GetMissedSize());
        }
        pNZBInfo->SetRemainingSize(pNZBInfo->GetRemainingSize() - pFileInfo->GetRemainingSize());
        if (pFileInfo->GetPaused())
        {
            pNZBInfo->SetPausedSize(pNZBInfo->GetPausedSize() - pFileInfo->GetRemainingSize());
        }
    }

    if (pFileInfo->GetParFile())
    {
        pNZBInfo->SetRemainingParCount(pNZBInfo->GetRemainingParCount() - 1);
    }
    if (pFileInfo->GetPaused())
    {
        pNZBInfo->SetPausedFileCount(pNZBInfo->GetPausedFileCount() - 1);
    }
}
Example #2
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);
}
Example #3
0
/*
 * Returns next article for download.
 */
bool QueueCoordinator::GetNextArticle(DownloadQueue* pDownloadQueue, FileInfo* &pFileInfo, ArticleInfo* &pArticleInfo)
{
    // find an unpaused file with the highest priority, then take the next article from the file.
    // if the file doesn't have any articles left for download, we store that fact and search again,
    // ignoring all files which were previously marked as not having any articles.

    // special case: if the file has ExtraPriority-flag set, it has the highest priority and the
    // Paused-flag is ignored.

    //debug("QueueCoordinator::GetNextArticle()");

    bool bOK = false;

    // pCheckedFiles stores
    bool* pCheckedFiles = NULL;
    time_t tCurDate = time(NULL);

    while (!bOK)
    {
        pFileInfo = NULL;
        int iNum = 0;
        int iFileNum = 0;

        for (NZBList::iterator it = pDownloadQueue->GetQueue()->begin(); it != pDownloadQueue->GetQueue()->end(); it++)
        {
            NZBInfo* pNZBInfo = *it;
            for (FileList::iterator it2 = pNZBInfo->GetFileList()->begin(); it2 != pNZBInfo->GetFileList()->end(); it2++)
            {
                FileInfo* pFileInfo1 = *it2;
                if ((!pCheckedFiles || !pCheckedFiles[iNum]) &&
                        !pFileInfo1->GetPaused() && !pFileInfo1->GetDeleted() &&
                        (g_pOptions->GetPropagationDelay() == 0 ||
                         (int)pFileInfo1->GetTime() < (int)tCurDate - g_pOptions->GetPropagationDelay()) &&
                        (!g_pOptions->GetPauseDownload() || pNZBInfo->GetForcePriority()) &&
                        (!pFileInfo ||
                         (pFileInfo1->GetExtraPriority() == pFileInfo->GetExtraPriority() &&
                          pFileInfo1->GetNZBInfo()->GetPriority() > pFileInfo->GetNZBInfo()->GetPriority()) ||
                         (pFileInfo1->GetExtraPriority() > pFileInfo->GetExtraPriority())))
                {
                    pFileInfo = pFileInfo1;
                    iFileNum = iNum;
                }
                iNum++;
            }
        }

        if (!pFileInfo)
        {
            // there are no more files for download
            break;
        }

        if (pFileInfo->GetArticles()->empty() && g_pOptions->GetSaveQueue() && g_pOptions->GetServerMode())
        {
            g_pDiskState->LoadArticles(pFileInfo);
        }

        // check if the file has any articles left for download
        for (FileInfo::Articles::iterator at = pFileInfo->GetArticles()->begin(); at != pFileInfo->GetArticles()->end(); at++)
        {
            pArticleInfo = *at;
            if (pArticleInfo->GetStatus() == ArticleInfo::aiUndefined)
            {
                bOK = true;
                break;
            }
        }

        if (!bOK)
        {
            // the file doesn't have any articles left for download, we mark the file as such
            if (!pCheckedFiles)
            {
                int iTotalFileCount = 0;
                for (NZBList::iterator it = pDownloadQueue->GetQueue()->begin(); it != pDownloadQueue->GetQueue()->end(); it++)
                {
                    NZBInfo* pNZBInfo = *it;
                    iTotalFileCount += pNZBInfo->GetFileList()->size();
                }

                if (iTotalFileCount > 0)
                {
                    int iArrSize = sizeof(bool) * iTotalFileCount;
                    pCheckedFiles = (bool*)malloc(iArrSize);
                    memset(pCheckedFiles, false, iArrSize);
                }
            }
            if (pCheckedFiles)
            {
                pCheckedFiles[iFileNum] = true;
            }
        }
    }

    free(pCheckedFiles);

    return bOK;
}
Example #4
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();
}
Example #5
0
void QueueCoordinator::AddNZBFileToQueue(NZBFile* pNZBFile, NZBInfo* pUrlInfo, bool bAddFirst)
{
    debug("Adding NZBFile to queue");

    NZBInfo* pNZBInfo = pNZBFile->GetNZBInfo();

    DownloadQueue* pDownloadQueue = DownloadQueue::Lock();

    DownloadQueue::Aspect foundAspect = { DownloadQueue::eaNzbFound, pDownloadQueue, pNZBInfo, NULL };
    pDownloadQueue->Notify(&foundAspect);

    NZBInfo::EDeleteStatus eDeleteStatus = pNZBInfo->GetDeleteStatus();

    if (eDeleteStatus != NZBInfo::dsNone)
    {
        bool bAllPaused = !pNZBInfo->GetFileList()->empty();
        for (FileList::iterator it = pNZBInfo->GetFileList()->begin(); it != pNZBInfo->GetFileList()->end(); it++)
        {
            FileInfo* pFileInfo = *it;
            bAllPaused &= pFileInfo->GetPaused();
            if (g_pOptions->GetSaveQueue() && g_pOptions->GetServerMode())
            {
                g_pDiskState->DiscardFile(pFileInfo, true, false, false);
            }
        }
        pNZBInfo->SetDeletePaused(bAllPaused);
    }

    if (eDeleteStatus != NZBInfo::dsManual)
    {
        // NZBInfo will be added either to queue or to history as duplicate
        // and therefore can be detached from NZBFile.
        pNZBFile->DetachNZBInfo();
    }

    if (eDeleteStatus == NZBInfo::dsNone)
    {
        if (g_pOptions->GetDupeCheck() && pNZBInfo->GetDupeMode() != dmForce)
        {
            CheckDupeFileInfos(pNZBInfo);
        }

        if (pUrlInfo)
        {
            // insert at the URL position
            for (NZBList::iterator it = pDownloadQueue->GetQueue()->begin(); it != pDownloadQueue->GetQueue()->end(); it++)
            {
                NZBInfo* pPosNzbInfo = *it;
                if (pPosNzbInfo == pUrlInfo)
                {
                    pDownloadQueue->GetQueue()->insert(it, pNZBInfo);
                    break;
                }
            }
        }
        else if (bAddFirst)
        {
            pDownloadQueue->GetQueue()->push_front(pNZBInfo);
        }
        else
        {
            pDownloadQueue->GetQueue()->push_back(pNZBInfo);
        }
    }

    if (pUrlInfo)
    {
        pNZBInfo->SetID(pUrlInfo->GetID());
        pDownloadQueue->GetQueue()->Remove(pUrlInfo);
        delete pUrlInfo;
    }

    if (eDeleteStatus == NZBInfo::dsNone)
    {
        pNZBInfo->PrintMessage(Message::mkInfo, "Collection %s added to queue", pNZBInfo->GetName());
    }

    if (eDeleteStatus != NZBInfo::dsManual)
    {
        DownloadQueue::Aspect addedAspect = { DownloadQueue::eaNzbAdded, pDownloadQueue, pNZBInfo, NULL };
        pDownloadQueue->Notify(&addedAspect);
    }

    pDownloadQueue->Save();

    DownloadQueue::Unlock();
}
Example #6
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();
}
Example #7
0
/*
 * Creates new nzb-item out of existing files from other nzb-items.
 * If any of file-items is being downloaded the command fail.
 * For each file-item an event "eaFileDeleted" is fired.
 */
bool QueueCoordinator::SplitQueueEntries(DownloadQueue* pDownloadQueue, FileList* pFileList, const char* szName, NZBInfo** pNewNZBInfo)
{
    if (pFileList->empty())
    {
        return false;
    }

    NZBInfo* pSrcNZBInfo = NULL;

    for (FileList::iterator it = pFileList->begin(); it != pFileList->end(); it++)
    {
        FileInfo* pFileInfo = *it;
        if (pFileInfo->GetActiveDownloads() > 0 || pFileInfo->GetCompletedArticles() > 0)
        {
            error("Could not split %s. File is already (partially) downloaded", pFileInfo->GetFilename());
            return false;
        }
        if (pFileInfo->GetNZBInfo()->GetPostInfo())
        {
            error("Could not split %s. File in post-process-stage", pFileInfo->GetFilename());
            return false;
        }
        if (!pSrcNZBInfo)
        {
            pSrcNZBInfo = pFileInfo->GetNZBInfo();
        }
    }

    NZBInfo* pNZBInfo = new NZBInfo();
    pDownloadQueue->GetQueue()->push_back(pNZBInfo);

    pNZBInfo->SetFilename(pSrcNZBInfo->GetFilename());
    pNZBInfo->SetName(szName);
    pNZBInfo->SetCategory(pSrcNZBInfo->GetCategory());
    pNZBInfo->SetFullContentHash(0);
    pNZBInfo->SetFilteredContentHash(0);
    pNZBInfo->SetPriority(pSrcNZBInfo->GetPriority());
    pNZBInfo->BuildDestDirName();
    pNZBInfo->SetQueuedFilename(pSrcNZBInfo->GetQueuedFilename());
    pNZBInfo->GetParameters()->CopyFrom(pSrcNZBInfo->GetParameters());

    pSrcNZBInfo->SetFullContentHash(0);
    pSrcNZBInfo->SetFilteredContentHash(0);

    for (FileList::iterator it = pFileList->begin(); it != pFileList->end(); it++)
    {
        FileInfo* pFileInfo = *it;

        DownloadQueue::Aspect aspect = { DownloadQueue::eaFileDeleted, pDownloadQueue, pFileInfo->GetNZBInfo(), pFileInfo };
        pDownloadQueue->Notify(&aspect);

        pFileInfo->SetNZBInfo(pNZBInfo);
        pNZBInfo->GetFileList()->push_back(pFileInfo);
        pSrcNZBInfo->GetFileList()->Remove(pFileInfo);

        pSrcNZBInfo->SetFileCount(pSrcNZBInfo->GetFileCount() - 1);
        pSrcNZBInfo->SetSize(pSrcNZBInfo->GetSize() - pFileInfo->GetSize());
        pSrcNZBInfo->SetRemainingSize(pSrcNZBInfo->GetRemainingSize() - pFileInfo->GetRemainingSize());
        pSrcNZBInfo->SetCurrentSuccessSize(pSrcNZBInfo->GetCurrentSuccessSize() - pFileInfo->GetSuccessSize());
        pSrcNZBInfo->SetCurrentFailedSize(pSrcNZBInfo->GetCurrentFailedSize() - pFileInfo->GetFailedSize() - pFileInfo->GetMissedSize());
        pSrcNZBInfo->SetTotalArticles(pSrcNZBInfo->GetTotalArticles() - pFileInfo->GetTotalArticles());
        pSrcNZBInfo->SetCurrentSuccessArticles(pSrcNZBInfo->GetCurrentSuccessArticles() - pFileInfo->GetSuccessArticles());
        pSrcNZBInfo->SetCurrentFailedArticles(pSrcNZBInfo->GetCurrentFailedArticles() - pFileInfo->GetFailedArticles());
        pSrcNZBInfo->GetCurrentServerStats()->ListOp(pFileInfo->GetServerStats(), ServerStatList::soSubtract);

        pNZBInfo->SetFileCount(pNZBInfo->GetFileCount() + 1);
        pNZBInfo->SetSize(pNZBInfo->GetSize() + pFileInfo->GetSize());
        pNZBInfo->SetRemainingSize(pNZBInfo->GetRemainingSize() + pFileInfo->GetRemainingSize());
        pNZBInfo->SetCurrentSuccessSize(pNZBInfo->GetCurrentSuccessSize() + pFileInfo->GetSuccessSize());
        pNZBInfo->SetCurrentFailedSize(pNZBInfo->GetCurrentFailedSize() + pFileInfo->GetFailedSize() + pFileInfo->GetMissedSize());
        pNZBInfo->SetTotalArticles(pNZBInfo->GetTotalArticles() + pFileInfo->GetTotalArticles());
        pNZBInfo->SetCurrentSuccessArticles(pNZBInfo->GetCurrentSuccessArticles() + pFileInfo->GetSuccessArticles());
        pNZBInfo->SetCurrentFailedArticles(pNZBInfo->GetCurrentFailedArticles() + pFileInfo->GetFailedArticles());
        pNZBInfo->GetCurrentServerStats()->ListOp(pFileInfo->GetServerStats(), ServerStatList::soAdd);

        if (pFileInfo->GetParFile())
        {
            pSrcNZBInfo->SetParSize(pSrcNZBInfo->GetParSize() - pFileInfo->GetSize());
            pSrcNZBInfo->SetParCurrentSuccessSize(pSrcNZBInfo->GetParCurrentSuccessSize() - pFileInfo->GetSuccessSize());
            pSrcNZBInfo->SetParCurrentFailedSize(pSrcNZBInfo->GetParCurrentFailedSize() - pFileInfo->GetFailedSize() - pFileInfo->GetMissedSize());
            pSrcNZBInfo->SetRemainingParCount(pSrcNZBInfo->GetRemainingParCount() - 1);

            pNZBInfo->SetParSize(pNZBInfo->GetParSize() + pFileInfo->GetSize());
            pNZBInfo->SetParCurrentSuccessSize(pNZBInfo->GetParCurrentSuccessSize() + pFileInfo->GetSuccessSize());
            pNZBInfo->SetParCurrentFailedSize(pNZBInfo->GetParCurrentFailedSize() + pFileInfo->GetFailedSize() + pFileInfo->GetMissedSize());
            pNZBInfo->SetRemainingParCount(pNZBInfo->GetRemainingParCount() + 1);
        }

        if (pFileInfo->GetPaused())
        {
            pSrcNZBInfo->SetPausedFileCount(pSrcNZBInfo->GetPausedFileCount() - 1);
            pSrcNZBInfo->SetPausedSize(pSrcNZBInfo->GetPausedSize() - pFileInfo->GetRemainingSize());

            pNZBInfo->SetPausedFileCount(pSrcNZBInfo->GetPausedFileCount() + 1);
            pNZBInfo->SetPausedSize(pNZBInfo->GetPausedSize() + pFileInfo->GetRemainingSize());
        }
    }

    pNZBInfo->UpdateMinMaxTime();
    if (pSrcNZBInfo->GetCompletedFiles()->empty())
    {
        pSrcNZBInfo->UpdateMinMaxTime();
    }

    if (pSrcNZBInfo->GetFileList()->empty())
    {
        pDownloadQueue->GetQueue()->Remove(pSrcNZBInfo);
        g_pDiskState->DiscardFiles(pSrcNZBInfo);
        delete pSrcNZBInfo;
    }

    *pNewNZBInfo = pNZBInfo;
    return true;
}
Example #8
0
bool Scanner::AddFileToQueue(const char* szFilename, const char* szNZBName, const char* szCategory,
	int iPriority, const char* szDupeKey, int iDupeScore, EDupeMode eDupeMode,
	NZBParameterList* pParameters, bool bAddTop, bool bAddPaused, NZBInfo* pUrlInfo, int* pNZBID)
{
	const char* szBasename = Util::BaseFileName(szFilename);

	info("Adding collection %s to queue", szBasename);

	NZBFile* pNZBFile = NZBFile::Create(szFilename, szCategory);
	bool bOK = pNZBFile != NULL;
	if (!bOK)
	{
		error("Could not add collection %s to queue", szBasename);
	}

	char bakname2[1024];
	if (!Util::RenameBak(szFilename, pNZBFile ? "queued" : "error", false, bakname2, 1024))
	{
		bOK = false;
		char szSysErrStr[256];
		error("Could not rename file %s to %s: %s", szFilename, bakname2, Util::GetLastErrorMessage(szSysErrStr, sizeof(szSysErrStr)));
	}

	if (bOK)
	{
		NZBInfo* pNZBInfo = pNZBFile->GetNZBInfo();
		pNZBInfo->SetQueuedFilename(bakname2);

		if (szNZBName && strlen(szNZBName) > 0)
		{
			pNZBInfo->SetName(NULL);
#ifdef WIN32
			char* szAnsiFilename = strdup(szNZBName);
			WebUtil::Utf8ToAnsi(szAnsiFilename, strlen(szAnsiFilename) + 1);
			pNZBInfo->SetFilename(szAnsiFilename);
			free(szAnsiFilename);
#else
			pNZBInfo->SetFilename(szNZBName);
#endif
			pNZBInfo->BuildDestDirName();
		}

		pNZBInfo->SetDupeKey(szDupeKey);
		pNZBInfo->SetDupeScore(iDupeScore);
		pNZBInfo->SetDupeMode(eDupeMode);
		pNZBInfo->SetPriority(iPriority);
		if (pUrlInfo)
		{
			pNZBInfo->SetURL(pUrlInfo->GetURL());
			pNZBInfo->SetUrlStatus(pUrlInfo->GetUrlStatus());
		}

		if (pNZBFile->GetPassword())
		{
			pNZBInfo->GetParameters()->SetParameter("*Unpack:Password", pNZBFile->GetPassword());
		}

		pNZBInfo->GetParameters()->CopyFrom(pParameters);

		for (::FileList::iterator it = pNZBInfo->GetFileList()->begin(); it != pNZBInfo->GetFileList()->end(); it++)
		{
			FileInfo* pFileInfo = *it;
			pFileInfo->SetPaused(bAddPaused);
		}

		g_pQueueCoordinator->AddNZBFileToQueue(pNZBFile, pUrlInfo, bAddTop);

		if (pNZBID)
		{
			*pNZBID = pNZBInfo->GetID();
		}
	}

	delete pNZBFile;

	return bOK;
}
Example #9
0
void Scanner::ProcessIncomingFile(const char* szDirectory, const char* szBaseFilename,
	const char* szFullFilename, const char* szCategory)
{
	const char* szExtension = strrchr(szBaseFilename, '.');
	if (!szExtension)
	{
		return;
	}

	char* szNZBName = strdup("");
	char* szNZBCategory = strdup(szCategory);
	NZBParameterList* pParameters = new NZBParameterList();
	int iPriority = 0;
	bool bAddTop = false;
	bool bAddPaused = false;
	char* szDupeKey = strdup("");
	int iDupeScore = 0;
	EDupeMode eDupeMode = dmScore;
	EAddStatus eAddStatus = asSkipped;
	bool bAdded = false;
	QueueData* pQueueData = NULL;
	NZBInfo* pUrlInfo = NULL;
	int iNZBID = 0;

	for (QueueList::iterator it = m_QueueList.begin(); it != m_QueueList.end(); it++)
    {
		QueueData* pQueueData1 = *it;
		if (Util::SameFilename(pQueueData1->GetFilename(), szFullFilename))
		{
			pQueueData = pQueueData1;
			free(szNZBName);
			szNZBName = strdup(pQueueData->GetNZBName());
			free(szNZBCategory);
			szNZBCategory = strdup(pQueueData->GetCategory());
			iPriority = pQueueData->GetPriority();
			free(szDupeKey);
			szDupeKey = strdup(pQueueData->GetDupeKey());
			iDupeScore = pQueueData->GetDupeScore();
			eDupeMode = pQueueData->GetDupeMode();
			bAddTop = pQueueData->GetAddTop();
			bAddPaused = pQueueData->GetAddPaused();
			pParameters->CopyFrom(pQueueData->GetParameters());
			pUrlInfo = pQueueData->GetUrlInfo();
		}
	}

	InitPPParameters(szNZBCategory, pParameters, false);

	bool bExists = true;

	if (m_bScanScript && strcasecmp(szExtension, ".nzb_processed"))
	{
		ScanScriptController::ExecuteScripts(szFullFilename, 
			pUrlInfo ? pUrlInfo->GetURL() : "", szDirectory,
			&szNZBName, &szNZBCategory, &iPriority, pParameters, &bAddTop,
			&bAddPaused, &szDupeKey, &iDupeScore, &eDupeMode);
		bExists = Util::FileExists(szFullFilename);
		if (bExists && strcasecmp(szExtension, ".nzb"))
		{
			char bakname2[1024];
			bool bRenameOK = Util::RenameBak(szFullFilename, "processed", false, bakname2, 1024);
			if (!bRenameOK)
			{
				char szSysErrStr[256];
				error("Could not rename file %s to %s: %s", szFullFilename, bakname2, Util::GetLastErrorMessage(szSysErrStr, sizeof(szSysErrStr)));
			}
		}
	}

	if (!strcasecmp(szExtension, ".nzb_processed"))
	{
		char szRenamedName[1024];
		bool bRenameOK = Util::RenameBak(szFullFilename, "nzb", true, szRenamedName, 1024);
		if (bRenameOK)
		{
			bAdded = AddFileToQueue(szRenamedName, szNZBName, szNZBCategory, iPriority,
				szDupeKey, iDupeScore, eDupeMode, pParameters, bAddTop, bAddPaused, pUrlInfo, &iNZBID);
		}
		else
		{
			char szSysErrStr[256];
			error("Could not rename file %s to %s: %s", szFullFilename, szRenamedName, Util::GetLastErrorMessage(szSysErrStr, sizeof(szSysErrStr)));
			eAddStatus = asFailed;
		}
	}
	else if (bExists && !strcasecmp(szExtension, ".nzb"))
	{
		bAdded = AddFileToQueue(szFullFilename, szNZBName, szNZBCategory, iPriority,
			szDupeKey, iDupeScore, eDupeMode, pParameters, bAddTop, bAddPaused, pUrlInfo, &iNZBID);
	}

	delete pParameters;

	free(szNZBName);
	free(szNZBCategory);
	free(szDupeKey);

	if (pQueueData)
	{
		pQueueData->SetAddStatus(eAddStatus == asFailed ? asFailed : bAdded ? asSuccess : asSkipped);
		pQueueData->SetNZBID(iNZBID);
	}
}