void NCursesFrontend::PrintGroupQueue() { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); int lineNr = m_queueWinTop; if (downloadQueue->GetQueue()->empty()) { BString<1024> buffer("%s NZBs for downloading", m_useColor ? "" : "*** "); PrintTopHeader(buffer, lineNr++, false); PlotLine("Ready to receive nzb-job", lineNr++, 0, NCURSES_COLORPAIR_TEXT); } else { lineNr++; ResetColWidths(); int calcLineNr = lineNr; int i = 0; for (NzbInfo* nzbInfo : downloadQueue->GetQueue()) { if (i >= m_queueScrollOffset && i < m_queueScrollOffset + m_queueWinHeight -1) { PrintGroupname(nzbInfo, calcLineNr++, false, true); } i++; } int64 remaining = 0; int64 paused = 0; i = 0; for (NzbInfo* nzbInfo : downloadQueue->GetQueue()) { if (i >= m_queueScrollOffset && i < m_queueScrollOffset + m_queueWinHeight -1) { PrintGroupname(nzbInfo, lineNr++, i == m_selectedQueueEntry, false); } i++; remaining += nzbInfo->GetRemainingSize(); paused += nzbInfo->GetPausedSize(); } BString<1024> buffer(" %sNZBs for downloading - %i NZBs in queue - %s / %s", m_useColor ? "" : "*** ", (int)downloadQueue->GetQueue()->size(), *Util::FormatSize(remaining), *Util::FormatSize(remaining - paused)); PrintTopHeader(buffer, m_queueWinTop, false); } }
int NCursesFrontend::CalcQueueSize() { int queueSize = 0; if (m_groupFiles) { queueSize = DownloadQueue::Guard()->GetQueue()->size(); } else { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); for (NzbInfo* nzbInfo : downloadQueue->GetQueue()) { queueSize += nzbInfo->GetFileList()->size(); } } return queueSize; }
void NCursesFrontend::PrintFileQueue() { int lineNr = m_queueWinTop + 1; int64 remaining = 0; int64 paused = 0; int pausedFiles = 0; int fileNum = 0; GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); for (NzbInfo* nzbInfo : downloadQueue->GetQueue()) { for (FileInfo* fileInfo : nzbInfo->GetFileList()) { if (fileNum >= m_queueScrollOffset && fileNum < m_queueScrollOffset + m_queueWinHeight -1) { PrintFilename(fileInfo, lineNr++, fileNum == m_selectedQueueEntry); } fileNum++; if (fileInfo->GetPaused()) { pausedFiles++; paused += fileInfo->GetRemainingSize(); } remaining += fileInfo->GetRemainingSize(); } } if (fileNum > 0) { BString<1024> header(" %sFiles for downloading - %i / %i files in queue - %s / %s", m_useColor ? "" : "*** ", fileNum, fileNum - pausedFiles, *Util::FormatSize(remaining), *Util::FormatSize(remaining - paused)); PrintTopHeader(header, m_queueWinTop, true); } else { lineNr--; BString<1024> header("%s Files for downloading", m_useColor ? "" : "*** "); PrintTopHeader(header, lineNr++, true); PlotLine("Ready to receive nzb-job", lineNr++, 0, NCURSES_COLORPAIR_TEXT); } }
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(); }
bool ArticleCache::CheckFlush(bool flushEverything) { debug("Checking cache, Allocated: %i, FlushEverything: %i", (int)m_allocated, (int)flushEverything); BString<1024> infoName; { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); for (NzbInfo* nzbInfo : downloadQueue->GetQueue()) { if (m_fileInfo) { break; } for (FileInfo* fileInfo : nzbInfo->GetFileList()) { if (fileInfo->GetCachedArticles() > 0 && (fileInfo->GetActiveDownloads() == 0 || flushEverything)) { m_fileInfo = fileInfo; infoName.Format("%s%c%s", m_fileInfo->GetNzbInfo()->GetName(), PATH_SEPARATOR, m_fileInfo->GetFilename()); break; } } } } if (m_fileInfo) { ArticleWriter articleWriter; articleWriter.SetFileInfo(m_fileInfo); articleWriter.SetInfoName(infoName); articleWriter.FlushCache(); m_fileInfo = nullptr; return true; } debug("Checking cache... nothing to flush"); return false; }
void PrePostProcessor::Stop() { Thread::Stop(); GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); for (NzbInfo* postJob : m_activeJobs) { if (postJob->GetPostInfo() && postJob->GetPostInfo()->GetPostThread()) { postJob->GetPostInfo()->GetPostThread()->Stop(); } } for (NzbInfo* nzbInfo : downloadQueue->GetQueue()) { if (nzbInfo->GetUnpackThread()) { ((DirectUnpack*)nzbInfo->GetUnpackThread())->Stop(downloadQueue, nzbInfo); } } }
/** * Reset the state of items after reloading from disk and * delete items which could not be resumed. * Also count the number of post-jobs. */ void PrePostProcessor::SanitisePostQueue() { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); for (NzbInfo* nzbInfo : downloadQueue->GetQueue()) { PostInfo* postInfo = nzbInfo->GetPostInfo(); if (postInfo) { m_jobCount++; if (postInfo->GetStage() == PostInfo::ptExecutingScript || !FileSystem::DirectoryExists(nzbInfo->GetDestDir())) { postInfo->SetStage(PostInfo::ptFinished); } else { postInfo->SetStage(PostInfo::ptQueued); } } } }
bool Frontend::PrepareData() { if (IsRemoteMode()) { if (IsStopped()) { return false; } if (!RequestMessages() || ((m_summary || m_fileList) && !RequestFileList())) { const char* controlIp = !strcmp(g_Options->GetControlIp(), "0.0.0.0") ? "127.0.0.1" : g_Options->GetControlIp(); printf("\nUnable to send request to nzbget-server at %s (port %i) \n", controlIp, g_Options->GetControlPort()); Stop(); return false; } } else { if (m_summary) { m_currentDownloadSpeed = g_StatMeter->CalcCurrentDownloadSpeed(); m_pauseDownload = g_Options->GetPauseDownload(); m_downloadLimit = g_Options->GetDownloadRate(); m_threadCount = Thread::GetThreadCount(); g_StatMeter->CalcTotalStat(&m_upTimeSec, &m_dnTimeSec, &m_allBytes, &m_standBy); GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); m_postJobCount = 0; for (NzbInfo* nzbInfo : downloadQueue->GetQueue()) { m_postJobCount += nzbInfo->GetPostInfo() ? 1 : 0; } downloadQueue->CalcRemainingSize(&m_remainingSize, nullptr); } } return true; }
bool NCursesFrontend::EditQueue(DownloadQueue::EEditAction action, int offset) { int ID = 0; if (m_groupFiles) { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); if (m_selectedQueueEntry >= 0 && m_selectedQueueEntry < (int)downloadQueue->GetQueue()->size()) { std::unique_ptr<NzbInfo>& nzbInfo = downloadQueue->GetQueue()->at(m_selectedQueueEntry); ID = nzbInfo->GetId(); if (action == DownloadQueue::eaFilePause) { if (nzbInfo->GetRemainingSize() == nzbInfo->GetPausedSize()) { action = DownloadQueue::eaFileResume; } else if (nzbInfo->GetPausedSize() == 0 && (nzbInfo->GetRemainingParCount() > 0) && !(m_lastPausePars && m_lastEditEntry == m_selectedQueueEntry)) { action = DownloadQueue::eaFilePauseExtraPars; m_lastPausePars = true; } else { action = DownloadQueue::eaFilePause; m_lastPausePars = false; } } } // map file-edit-actions to group-edit-actions DownloadQueue::EEditAction FileToGroupMap[] = { (DownloadQueue::EEditAction)0, DownloadQueue::eaGroupMoveOffset, DownloadQueue::eaGroupMoveTop, DownloadQueue::eaGroupMoveBottom, DownloadQueue::eaGroupPause, DownloadQueue::eaGroupResume, DownloadQueue::eaGroupDelete, DownloadQueue::eaGroupPauseAllPars, DownloadQueue::eaGroupPauseExtraPars }; action = FileToGroupMap[action]; } else { int fileNum = 0; GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); for (NzbInfo* nzbInfo : downloadQueue->GetQueue()) { for (FileInfo* fileInfo : nzbInfo->GetFileList()) { if (m_selectedQueueEntry == fileNum) { ID = fileInfo->GetId(); if (action == DownloadQueue::eaFilePause) { action = !fileInfo->GetPaused() ? DownloadQueue::eaFilePause : DownloadQueue::eaFileResume; } } fileNum++; } } } m_lastEditEntry = m_selectedQueueEntry; NeedUpdateData(); if (ID != 0) { return ServerEditQueue(action, offset, ID); } else { return false; } }
void WinConsole::UpdateTrayIcon() { if (!m_showTrayIcon) { return; } HICON hOldIcon = m_iconData->hIcon; char oldTip[200]; strncpy(oldTip, m_iconData->szTip, sizeof(m_iconData->szTip)); oldTip[200-1] = '\0'; if (g_Options->GetPauseDownload()) { m_iconData->hIcon = m_pausedIcon; strncpy(m_iconData->szTip, "NZBGet - paused", sizeof(m_iconData->szTip)); } else if (!g_StatMeter->GetStandBy()) { m_iconData->hIcon = m_workingIcon; BString<100> tip("NZBGet - downloading at %s", *Util::FormatSpeed(g_StatMeter->CalcCurrentDownloadSpeed())); strncpy(m_iconData->szTip, tip, sizeof(m_iconData->szTip)); } else { int postJobCount = 0; int urlCount = 0; { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); for (NzbInfo* nzbInfo : downloadQueue->GetQueue()) { postJobCount += nzbInfo->GetPostInfo() ? 1 : 0; urlCount += nzbInfo->GetKind() == NzbInfo::nkUrl ? 1 : 0; } } if (postJobCount > 0) { m_iconData->hIcon = m_workingIcon; strncpy(m_iconData->szTip, "NZBGet - post-processing", sizeof(m_iconData->szTip)); } else if (urlCount > 0) { m_iconData->hIcon = m_workingIcon; strncpy(m_iconData->szTip, "NZBGet - fetching URLs", sizeof(m_iconData->szTip)); } else if (g_FeedCoordinator->HasActiveDownloads()) { m_iconData->hIcon = m_workingIcon; strncpy(m_iconData->szTip, "NZBGet - fetching feeds", sizeof(m_iconData->szTip)); } else { m_iconData->hIcon = m_idleIcon; strncpy(m_iconData->szTip, "NZBGet - idle", sizeof(m_iconData->szTip)); } } if (m_iconData->hIcon != hOldIcon || strcmp(oldTip, m_iconData->szTip)) { Shell_NotifyIcon(NIM_MODIFY, m_iconData); } }
void PrePostProcessor::WaitJobs() { debug("PrePostProcessor: waiting for jobs to complete"); // wait 5 seconds until all post-processing jobs gracefully finish time_t waitStart = Util::CurrentTime(); while (Util::CurrentTime() < waitStart + 5) { { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); if (m_activeJobs.empty()) { break; } } CheckPostQueue(); usleep(200 * 1000); } // kill remaining post-processing jobs; not safe but we can't wait any longer { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); for (NzbInfo* postJob : m_activeJobs) { if (postJob->GetPostInfo() && postJob->GetPostInfo()->GetPostThread()) { Thread* thread = postJob->GetPostInfo()->GetPostThread(); postJob->GetPostInfo()->SetPostThread(nullptr); warn("Terminating active post-process job for %s", postJob->GetName()); thread->Kill(); delete thread; } } } // wait 5 seconds until direct unpack threads gracefully finish waitStart = Util::CurrentTime(); while (Util::CurrentTime() < waitStart + 5) { { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); if (std::find_if(downloadQueue->GetQueue()->begin(), downloadQueue->GetQueue()->end(), [](const std::unique_ptr<NzbInfo>& nzbInfo) { return nzbInfo->GetUnpackThread() != nullptr; }) == downloadQueue->GetQueue()->end()) { break; } } usleep(200 * 1000); } // disconnect remaining direct unpack jobs { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); for (NzbInfo* nzbInfo : downloadQueue->GetQueue()) { nzbInfo->SetUnpackThread(nullptr); } } debug("PrePostProcessor: Jobs are completed"); }
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()); } }