bool PrePostProcessor::PostQueueDelete(DownloadQueue* downloadQueue, IdList* idList) { bool ok = false; for (int id : *idList) { for (NzbInfo* nzbInfo: downloadQueue->GetQueue()) { PostInfo* postInfo = nzbInfo->GetPostInfo(); if (postInfo && nzbInfo->GetId() == id) { if (postInfo->GetWorking()) { postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo, "Deleting active post-job %s", postInfo->GetNzbInfo()->GetName()); postInfo->SetDeleted(true); if (postInfo->GetPostThread()) { debug("Terminating post-process thread for %s", postInfo->GetNzbInfo()->GetName()); postInfo->GetPostThread()->Stop(); ok = true; } else if (postInfo->GetNzbInfo()->GetUnpackThread()) { ((DirectUnpack*)postInfo->GetNzbInfo()->GetUnpackThread())->NzbDeleted(downloadQueue, postInfo->GetNzbInfo()); ok = true; } else { error("Internal error in PrePostProcessor::QueueDelete"); } } else { postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo, "Deleting queued post-job %s", postInfo->GetNzbInfo()->GetName()); JobCompleted(downloadQueue, postInfo); m_activeJobs.erase(std::remove_if(m_activeJobs.begin(), m_activeJobs.end(), [postInfo](NzbInfo* postJob) { return postInfo == postJob->GetPostInfo(); }), m_activeJobs.end()); ok = true; } break; } } } if (ok) { downloadQueue->Save(); } return ok; }
bool PrePostProcessor::PostQueueDelete(IDList* pIDList) { bool bOK = false; DownloadQueue* pDownloadQueue = g_pQueueCoordinator->LockQueue(); for (IDList::iterator itID = pIDList->begin(); itID != pIDList->end(); itID++) { int iID = *itID; for (PostQueue::iterator itPost = pDownloadQueue->GetPostQueue()->begin(); itPost != pDownloadQueue->GetPostQueue()->end(); itPost++) { PostInfo* pPostInfo = *itPost; if (pPostInfo->GetID() == iID) { if (pPostInfo->GetWorking()) { info("Deleting active post-job %s", pPostInfo->GetInfoName()); pPostInfo->SetDeleted(true); #ifndef DISABLE_PARCHECK if (PostInfo::ptLoadingPars <= pPostInfo->GetStage() && pPostInfo->GetStage() <= PostInfo::ptRenaming) { if (m_ParCoordinator.Cancel()) { bOK = true; } } else #endif if (pPostInfo->GetPostThread()) { debug("Terminating %s for %s", (pPostInfo->GetStage() == PostInfo::ptUnpacking ? "unpack" : "post-process-script"), pPostInfo->GetInfoName()); pPostInfo->GetPostThread()->Stop(); bOK = true; } else { error("Internal error in PrePostProcessor::QueueDelete"); } } else { info("Deleting queued post-job %s", pPostInfo->GetInfoName()); JobCompleted(pDownloadQueue, pPostInfo); bOK = true; } break; } } } g_pQueueCoordinator->UnlockQueue(); return bOK; }
bool PrePostProcessor::PostQueueDelete(DownloadQueue* downloadQueue, IdList* idList) { bool ok = false; for (int id : *idList) { for (NzbInfo* nzbInfo: downloadQueue->GetQueue()) { PostInfo* postInfo = nzbInfo->GetPostInfo(); if (postInfo && nzbInfo->GetId() == id) { if (postInfo->GetWorking()) { postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo, "Deleting active post-job %s", postInfo->GetNzbInfo()->GetName()); postInfo->SetDeleted(true); #ifndef DISABLE_PARCHECK if (PostInfo::ptLoadingPars <= postInfo->GetStage() && postInfo->GetStage() <= PostInfo::ptRenaming) { if (m_parCoordinator.Cancel()) { ok = true; } } else #endif if (postInfo->GetPostThread()) { debug("Terminating %s for %s", (postInfo->GetStage() == PostInfo::ptUnpacking ? "unpack" : "post-process-script"), postInfo->GetNzbInfo()->GetName()); postInfo->GetPostThread()->Stop(); ok = true; } else { error("Internal error in PrePostProcessor::QueueDelete"); } } else { postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo, "Deleting queued post-job %s", postInfo->GetNzbInfo()->GetName()); JobCompleted(downloadQueue, postInfo); ok = true; } break; } } } return ok; }
void PrePostProcessor::CheckPostQueue() { DownloadQueue* pDownloadQueue = g_pQueueCoordinator->LockQueue(); if (!pDownloadQueue->GetPostQueue()->empty()) { PostInfo* pPostInfo = pDownloadQueue->GetPostQueue()->front(); if (!pPostInfo->GetWorking()) { #ifndef DISABLE_PARCHECK if (pPostInfo->GetRequestParCheck() && pPostInfo->GetNZBInfo()->GetParStatus() <= NZBInfo::psSkipped && g_pOptions->GetParCheck() != Options::pcManual) { pPostInfo->GetNZBInfo()->SetParStatus(NZBInfo::psNone); pPostInfo->SetRequestParCheck(false); pPostInfo->SetStage(PostInfo::ptQueued); pPostInfo->GetNZBInfo()->GetScriptStatuses()->Clear(); DeletePostThread(pPostInfo); } else if (pPostInfo->GetRequestParCheck() && pPostInfo->GetNZBInfo()->GetParStatus() <= NZBInfo::psSkipped && g_pOptions->GetParCheck() == Options::pcManual) { pPostInfo->SetRequestParCheck(false); pPostInfo->GetNZBInfo()->SetParStatus(NZBInfo::psManual); DeletePostThread(pPostInfo); FileInfo* pFileInfo = GetQueueGroup(pDownloadQueue, pPostInfo->GetNZBInfo()); if (pFileInfo) { info("Downloading all remaining files for manual par-check for %s", pPostInfo->GetNZBInfo()->GetName()); g_pQueueCoordinator->GetQueueEditor()->LockedEditEntry(pDownloadQueue, pFileInfo->GetID(), false, QueueEditor::eaGroupResume, 0, NULL); pPostInfo->SetStage(PostInfo::ptFinished); pPostInfo->GetNZBInfo()->SetPostProcess(false); } else { info("There are no par-files remain for download for %s", pPostInfo->GetNZBInfo()->GetName()); pPostInfo->SetStage(PostInfo::ptQueued); } } else if (pPostInfo->GetRequestParRename()) { pPostInfo->GetNZBInfo()->SetRenameStatus(NZBInfo::rsNone); pPostInfo->SetRequestParRename(false); pPostInfo->SetStage(PostInfo::ptQueued); DeletePostThread(pPostInfo); } #endif if (pPostInfo->GetDeleted()) { pPostInfo->SetStage(PostInfo::ptFinished); } if (pPostInfo->GetStage() == PostInfo::ptQueued && !g_pOptions->GetPausePostProcess()) { DeletePostThread(pPostInfo); StartJob(pDownloadQueue, pPostInfo); } else if (pPostInfo->GetStage() == PostInfo::ptFinished) { UpdatePauseState(false, NULL); JobCompleted(pDownloadQueue, pPostInfo); } else if (!g_pOptions->GetPausePostProcess()) { error("Internal error: invalid state in post-processor"); } } } g_pQueueCoordinator->UnlockQueue(); }
int BaseJob::EvalOnExitJobExpr() { float old_run_time; bool old_run_time_dirty; UserPolicy user_policy; #ifdef USE_NON_MUTATING_USERPOLICY user_policy.Init(); #else user_policy.Init( jobAd ); #endif // The user policy code expects an exit value to be set // If the ON_EXIT attributes haven't been set at all, fake // a normal job exit. int dummy; if ( !jobAd->LookupInteger( ATTR_ON_EXIT_SIGNAL, dummy ) && !jobAd->LookupInteger( ATTR_ON_EXIT_CODE, dummy ) ) { exitStatusKnown = false; jobAd->Assign( ATTR_ON_EXIT_BY_SIGNAL, false ); jobAd->Assign( ATTR_ON_EXIT_CODE, 0 ); } else { exitStatusKnown = true; } // TODO: We should just mark the job as done running UpdateJobTime( &old_run_time, &old_run_time_dirty ); #ifdef USE_NON_MUTATING_USERPOLICY int action = user_policy.AnalyzePolicy( *jobAd, PERIODIC_THEN_EXIT ); #else int action = user_policy.AnalyzePolicy( PERIODIC_THEN_EXIT ); #endif RestoreJobTime( old_run_time, old_run_time_dirty ); if ( action != REMOVE_FROM_QUEUE ) { jobAd->Assign( ATTR_ON_EXIT_BY_SIGNAL, false ); jobAd->AssignExpr( ATTR_ON_EXIT_CODE, "Undefined" ); jobAd->AssignExpr( ATTR_ON_EXIT_SIGNAL, "Undefined" ); } MyString reason_buf; int reason_code; int reason_subcode; user_policy.FiringReason(reason_buf,reason_code,reason_subcode); const char *reason = reason_buf.Value(); if ( reason == NULL || !reason[0] ) { reason = "Unknown user policy expression"; } switch( action ) { case UNDEFINED_EVAL: case HOLD_IN_QUEUE: JobHeld( reason, reason_code, reason_subcode ); break; case STAYS_IN_QUEUE: // clean up job but don't set status to complete break; case REMOVE_FROM_QUEUE: JobCompleted(); break; default: EXCEPT( "Unknown action (%d) in BaseJob::EvalAtExitJobExpr", action ); } return 0; }
void PrePostProcessor::CheckPostQueue() { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); if (!m_curJob && m_jobCount > 0) { m_curJob = GetNextJob(downloadQueue); } if (m_curJob) { PostInfo* postInfo = m_curJob->GetPostInfo(); if (!postInfo->GetWorking() && !IsNzbFileDownloading(m_curJob)) { #ifndef DISABLE_PARCHECK if (postInfo->GetRequestParCheck() && (postInfo->GetNzbInfo()->GetParStatus() <= NzbInfo::psSkipped || (postInfo->GetForceRepair() && !postInfo->GetNzbInfo()->GetParFull())) && g_Options->GetParCheck() != Options::pcManual) { postInfo->SetForceParFull(postInfo->GetNzbInfo()->GetParStatus() > NzbInfo::psSkipped); postInfo->GetNzbInfo()->SetParStatus(NzbInfo::psNone); postInfo->SetRequestParCheck(false); postInfo->SetStage(PostInfo::ptQueued); postInfo->GetNzbInfo()->GetScriptStatuses()->clear(); DeletePostThread(postInfo); } else if (postInfo->GetRequestParCheck() && postInfo->GetNzbInfo()->GetParStatus() <= NzbInfo::psSkipped && g_Options->GetParCheck() == Options::pcManual) { postInfo->SetRequestParCheck(false); postInfo->GetNzbInfo()->SetParStatus(NzbInfo::psManual); DeletePostThread(postInfo); if (!postInfo->GetNzbInfo()->GetFileList()->empty()) { postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo, "Downloading all remaining files for manual par-check for %s", postInfo->GetNzbInfo()->GetName()); downloadQueue->EditEntry(postInfo->GetNzbInfo()->GetId(), DownloadQueue::eaGroupResume, 0, nullptr); postInfo->SetStage(PostInfo::ptFinished); } else { postInfo->GetNzbInfo()->PrintMessage(Message::mkInfo, "There are no par-files remain for download for %s", postInfo->GetNzbInfo()->GetName()); postInfo->SetStage(PostInfo::ptQueued); } } #endif if (postInfo->GetDeleted()) { postInfo->SetStage(PostInfo::ptFinished); } if (postInfo->GetStage() == PostInfo::ptQueued && (!g_Options->GetPausePostProcess() || postInfo->GetNzbInfo()->GetForcePriority())) { DeletePostThread(postInfo); StartJob(downloadQueue, postInfo); } else if (postInfo->GetStage() == PostInfo::ptFinished) { UpdatePauseState(false, nullptr); JobCompleted(downloadQueue, postInfo); } else if (!g_Options->GetPausePostProcess()) { error("Internal error: invalid state in post-processor"); // TODO: cancel (delete) current job } } } }