void PrePostProcessor::JobCompleted(DownloadQueue* downloadQueue, PostInfo* postInfo) { NzbInfo* nzbInfo = postInfo->GetNzbInfo(); if (postInfo->GetStartTime() > 0) { nzbInfo->SetPostTotalSec((int)(Util::CurrentTime() - postInfo->GetStartTime())); postInfo->SetStartTime(0); } DeletePostThread(postInfo); nzbInfo->LeavePostProcess(); if (IsNzbFileCompleted(nzbInfo, true)) { NzbCompleted(downloadQueue, nzbInfo, false); } if (nzbInfo == m_curJob) { m_curJob = nullptr; } m_jobCount--; downloadQueue->Save(); }
void QueueScriptCoordinator::CheckQueue() { if (m_stopped) { return; } m_curItem.reset(); GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); Guard guard(m_queueMutex); NzbInfo* curNzbInfo = nullptr; Queue::iterator itCurItem; for (Queue::iterator it = m_queue.begin(); it != m_queue.end(); ) { std::unique_ptr<QueueItem>& queueItem = *it; NzbInfo* nzbInfo = FindNzbInfo(downloadQueue, queueItem->GetNzbId()); // in a case this nzb must not be processed further - delete queue script from queue EEvent event = queueItem->GetEvent(); bool ignoreEvent = !nzbInfo || (nzbInfo->GetDeleteStatus() != NzbInfo::dsNone && event != qeNzbDeleted && event != qeNzbMarked) || (nzbInfo->GetMarkStatus() == NzbInfo::ksBad && event != qeNzbMarked); if (ignoreEvent) { it = m_queue.erase(it); if (curNzbInfo) { // process from the beginning, while "erase" invalidated "itCurItem" curNzbInfo = nullptr; it = m_queue.begin(); } continue; } if (!m_curItem || queueItem->GetEvent() > m_curItem->GetEvent()) { itCurItem = it; curNzbInfo = nzbInfo; } it++; } if (curNzbInfo) { m_curItem = std::move(*itCurItem); m_queue.erase(itCurItem); QueueScriptController::StartScript(curNzbInfo, m_curItem->GetScript(), m_curItem->GetEvent()); } }
void PrePostProcessor::JobCompleted(DownloadQueue* downloadQueue, PostInfo* postInfo) { NzbInfo* nzbInfo = postInfo->GetNzbInfo(); nzbInfo->LeavePostProcess(); if (nzbInfo->IsDownloadCompleted(true)) { NzbCompleted(downloadQueue, nzbInfo, false); } m_queuedJobs--; }
NzbInfo* PrePostProcessor::GetNextJob(DownloadQueue* downloadQueue) { NzbInfo* nzbInfo = nullptr; for (NzbInfo* nzbInfo1: downloadQueue->GetQueue()) { if (nzbInfo1->GetPostInfo() && !g_QueueScriptCoordinator->HasJob(nzbInfo1->GetId(), nullptr) && (!nzbInfo || nzbInfo1->GetPriority() > nzbInfo->GetPriority()) && (!g_Options->GetPausePostProcess() || nzbInfo1->GetForcePriority())) { nzbInfo = nzbInfo1; } } return nzbInfo; }
void QueueScriptController::Run() { ExecuteScript(m_script); SetLogPrefix(nullptr); if (m_markBad) { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); NzbInfo* nzbInfo = downloadQueue->GetQueue()->Find(m_id); if (nzbInfo) { PrintMessage(Message::mkWarning, "Cancelling download and deleting %s", *m_nzbName); nzbInfo->SetDeleteStatus(NzbInfo::dsBad); downloadQueue->EditEntry(m_id, DownloadQueue::eaGroupDelete, 0, nullptr); } } g_QueueScriptCoordinator->CheckQueue(); }
/* * Returns next URL for download. */ NzbInfo* UrlCoordinator::GetNextUrl(DownloadQueue* downloadQueue) { bool pauseDownload = g_Options->GetPauseDownload(); NzbInfo* nzbInfo = nullptr; for (NzbInfo* nzbInfo1 : downloadQueue->GetQueue()) { if (nzbInfo1->GetKind() == NzbInfo::nkUrl && nzbInfo1->GetUrlStatus() == NzbInfo::lsNone && nzbInfo1->GetDeleteStatus() == NzbInfo::dsNone && (!pauseDownload || g_Options->GetUrlForce()) && (!nzbInfo || nzbInfo1->GetPriority() > nzbInfo->GetPriority())) { nzbInfo = nzbInfo1; } } return nzbInfo; }
NzbInfo* PrePostProcessor::PickNextJob(DownloadQueue* downloadQueue, bool allowPar) { NzbInfo* nzbInfo = nullptr; for (NzbInfo* nzbInfo1: downloadQueue->GetQueue()) { if (nzbInfo1->GetPostInfo() && !nzbInfo1->GetPostInfo()->GetWorking() && !g_QueueScriptCoordinator->HasJob(nzbInfo1->GetId(), nullptr) && nzbInfo1->GetDirectUnpackStatus() != NzbInfo::nsRunning && (!nzbInfo || nzbInfo1->GetPriority() > nzbInfo->GetPriority()) && (!g_Options->GetPausePostProcess() || nzbInfo1->GetForcePriority()) && (allowPar || !nzbInfo1->GetPostInfo()->GetNeedParCheck()) && (std::find(m_activeJobs.begin(), m_activeJobs.end(), nzbInfo1) == m_activeJobs.end()) && nzbInfo1->IsDownloadCompleted(true)) { nzbInfo = nzbInfo1; } } return nzbInfo; }
void QueueEditor::ReorderFiles(ItemList* itemList) { if (itemList->size() == 0) { return; } EditItem& firstItem = itemList->front(); NzbInfo* nzbInfo = firstItem.m_fileInfo->GetNzbInfo(); uint32 insertPos = 0; // now can reorder for (EditItem& item : itemList) { FileInfo* fileInfo = item.m_fileInfo; // move file item FileList::iterator it2 = nzbInfo->GetFileList()->Find(fileInfo); if (it2 != nzbInfo->GetFileList()->end()) { std::unique_ptr<FileInfo> movedFileInfo = std::move(*it2); nzbInfo->GetFileList()->erase(it2); nzbInfo->GetFileList()->insert(nzbInfo->GetFileList()->begin() + insertPos, std::move(movedFileInfo)); insertPos++; } } }
void PrePostProcessor::CheckPostQueue() { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); size_t countBefore = m_activeJobs.size(); CheckRequestPar(downloadQueue); CleanupJobs(downloadQueue); bool changed = m_activeJobs.size() != countBefore; bool allowPar; while (CanRunMoreJobs(&allowPar) && !IsStopped()) { NzbInfo* postJob = PickNextJob(downloadQueue, allowPar); if (!postJob) { break; } m_activeJobs.push_back(postJob); PostInfo* postInfo = postJob->GetPostInfo(); if (postInfo->GetStage() == PostInfo::ptQueued && (!g_Options->GetPausePostProcess() || postInfo->GetNzbInfo()->GetForcePriority())) { StartJob(downloadQueue, postInfo, allowPar); CheckRequestPar(downloadQueue); CleanupJobs(downloadQueue); changed = true; } } if (changed) { downloadQueue->Save(); UpdatePauseState(); } Util::SetStandByMode(m_activeJobs.empty()); }
void QueueScriptController::AddMessage(Message::EKind kind, const char* text) { const char* msgText = text + m_prefixLen; if (!strncmp(msgText, "[NZB] ", 6)) { debug("Command %s detected", msgText + 6); if (!strncmp(msgText + 6, "NZBPR_", 6)) { CString param = msgText + 6 + 6; char* value = strchr(param, '='); if (value) { *value = '\0'; GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); NzbInfo* nzbInfo = QueueScriptCoordinator::FindNzbInfo(downloadQueue, m_id); if (nzbInfo) { nzbInfo->GetParameters()->SetParameter(param, value + 1); } } else { error("Invalid command \"%s\" received from %s", msgText, GetInfoName()); } } else if (!strncmp(msgText + 6, "DIRECTORY=", 10) && m_event == QueueScriptCoordinator::qeNzbDownloaded) { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); NzbInfo* nzbInfo = QueueScriptCoordinator::FindNzbInfo(downloadQueue, m_id); if (nzbInfo) { nzbInfo->SetFinalDir(msgText + 6 + 10); } } else if (!strncmp(msgText + 6, "MARK=BAD", 8)) { m_markBad = true; GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); NzbInfo* nzbInfo = QueueScriptCoordinator::FindNzbInfo(downloadQueue, m_id); if (nzbInfo) { SetLogPrefix(nullptr); PrintMessage(Message::mkWarning, "Marking %s as bad", *m_nzbName); SetLogPrefix(m_script->GetDisplayName()); nzbInfo->SetMarkStatus(NzbInfo::ksBad); } } else { error("Invalid command \"%s\" received from %s", msgText, GetInfoName()); } } else { NzbInfo* nzbInfo = nullptr; { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); nzbInfo = QueueScriptCoordinator::FindNzbInfo(downloadQueue, m_id); if (nzbInfo) { nzbInfo->AddMessage(kind, text); } } if (!nzbInfo) { ScriptController::AddMessage(kind, text); } } }
void UrlCoordinator::UrlCompleted(UrlDownloader* urlDownloader) { debug("URL downloaded"); NzbInfo* nzbInfo = urlDownloader->GetNzbInfo(); const char* origname; if (urlDownloader->GetOriginalFilename()) { origname = urlDownloader->GetOriginalFilename(); } else { origname = FileSystem::BaseFileName(nzbInfo->GetUrl()); // TODO: decode URL escaping } CString filename = FileSystem::MakeValidFilename(origname); debug("Filename: [%s]", *filename); bool retry; { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); // remove downloader from downloader list m_activeDownloads.erase(std::find(m_activeDownloads.begin(), m_activeDownloads.end(), urlDownloader)); nzbInfo->SetActiveDownloads(0); retry = urlDownloader->GetStatus() == WebDownloader::adRetry && !nzbInfo->GetDeleting(); if (nzbInfo->GetDeleting()) { nzbInfo->SetDeleteStatus(NzbInfo::dsManual); nzbInfo->SetUrlStatus(NzbInfo::lsNone); nzbInfo->SetDeleting(false); } else if (urlDownloader->GetStatus() == WebDownloader::adFinished) { nzbInfo->SetUrlStatus(NzbInfo::lsFinished); } else if (urlDownloader->GetStatus() == WebDownloader::adFailed) { nzbInfo->SetUrlStatus(NzbInfo::lsFailed); } else if (urlDownloader->GetStatus() == WebDownloader::adRetry) { nzbInfo->SetUrlStatus(NzbInfo::lsNone); } if (!retry) { DownloadQueue::Aspect aspect = {DownloadQueue::eaUrlCompleted, downloadQueue, nzbInfo, nullptr}; downloadQueue->Notify(&aspect); } } if (retry) { return; } if (nzbInfo->GetUrlStatus() == NzbInfo::lsFinished) { // add nzb-file to download queue Scanner::EAddStatus addStatus = g_Scanner->AddExternalFile( !Util::EmptyStr(nzbInfo->GetFilename()) ? nzbInfo->GetFilename() : *filename, !Util::EmptyStr(nzbInfo->GetCategory()) ? nzbInfo->GetCategory() : urlDownloader->GetCategory(), nzbInfo->GetPriority(), nzbInfo->GetDupeKey(), nzbInfo->GetDupeScore(), nzbInfo->GetDupeMode(), nzbInfo->GetParameters(), false, nzbInfo->GetAddUrlPaused(), nzbInfo, urlDownloader->GetOutputFilename(), nullptr, 0, nullptr); if (addStatus == Scanner::asSuccess) { // if scanner has successfully added nzb-file to queue, our pNZBInfo is // already removed from queue and destroyed return; } nzbInfo->SetUrlStatus(addStatus == Scanner::asFailed ? NzbInfo::lsScanFailed : NzbInfo::lsScanSkipped); } // the rest of function is only for failed URLs or for failed scans g_QueueScriptCoordinator->EnqueueScript(nzbInfo, QueueScriptCoordinator::qeUrlCompleted); std::unique_ptr<NzbInfo> oldNzbInfo; { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); // delete URL from queue oldNzbInfo = downloadQueue->GetQueue()->Remove(nzbInfo); // add failed URL to history if (g_Options->GetKeepHistory() > 0 && nzbInfo->GetUrlStatus() != NzbInfo::lsFinished && !nzbInfo->GetAvoidHistory()) { std::unique_ptr<HistoryInfo> historyInfo = std::make_unique<HistoryInfo>(std::move(oldNzbInfo)); historyInfo->SetTime(Util::CurrentTime()); downloadQueue->GetHistory()->Add(std::move(historyInfo), true); downloadQueue->HistoryChanged(); } downloadQueue->Save(); } if (oldNzbInfo) { g_DiskState->DiscardFiles(oldNzbInfo.get()); } }