void PrePostProcessor::JobCompleted(DownloadQueue* pDownloadQueue, PostInfo* pPostInfo) { pPostInfo->SetWorking(false); pPostInfo->SetProgressLabel(""); pPostInfo->SetStage(PostInfo::ptFinished); DeletePostThread(pPostInfo); if (IsNZBFileCompleted(pDownloadQueue, pPostInfo->GetNZBInfo(), true, false)) { // Cleaning up queue if par-check was successful or unpack was successful or // script was successful (if unpack was not performed) bool bCanCleanupQueue = pPostInfo->GetNZBInfo()->GetParStatus() == NZBInfo::psSuccess || pPostInfo->GetNZBInfo()->GetParStatus() == NZBInfo::psRepairPossible || pPostInfo->GetNZBInfo()->GetUnpackStatus() == NZBInfo::usSuccess || (pPostInfo->GetNZBInfo()->GetUnpackStatus() == NZBInfo::usNone && pPostInfo->GetNZBInfo()->GetScriptStatuses()->CalcTotalStatus() == ScriptStatus::srSuccess); if ((g_pOptions->GetParCleanupQueue() || g_pOptions->GetNzbCleanupDisk()) && bCanCleanupQueue) { if (g_pOptions->GetParCleanupQueue()) { FileInfo* pFileInfo = GetQueueGroup(pDownloadQueue, pPostInfo->GetNZBInfo()); if (pFileInfo) { info("Cleaning up download queue for %s", pPostInfo->GetNZBInfo()->GetName()); pFileInfo->GetNZBInfo()->ClearCompletedFiles(); pFileInfo->GetNZBInfo()->SetParCleanup(true); g_pQueueCoordinator->GetQueueEditor()->LockedEditEntry(pDownloadQueue, pFileInfo->GetID(), false, QueueEditor::eaGroupDelete, 0, NULL); } } if (g_pOptions->GetNzbCleanupDisk()) { DeleteQueuedFile(pPostInfo->GetNZBInfo()->GetQueuedFilename()); } } NZBCompleted(pDownloadQueue, pPostInfo->GetNZBInfo(), false); } for (PostQueue::iterator it = pDownloadQueue->GetPostQueue()->begin(); it != pDownloadQueue->GetPostQueue()->end(); it++) { if (pPostInfo == *it) { pDownloadQueue->GetPostQueue()->erase(it); break; } } delete pPostInfo; SaveQueue(pDownloadQueue); m_bHasMoreJobs = !pDownloadQueue->GetPostQueue()->empty(); }
void QueueEditor::AlignGroup(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo) { FileInfo* pLastFileInfo = NULL; unsigned int iLastNum = 0; unsigned int iNum = 0; while (iNum < pDownloadQueue->GetFileQueue()->size()) { FileInfo* pFileInfo = pDownloadQueue->GetFileQueue()->at(iNum); if (pFileInfo->GetNZBInfo() == pNZBInfo) { if (pLastFileInfo && iNum - iLastNum > 1) { pDownloadQueue->GetFileQueue()->erase(pDownloadQueue->GetFileQueue()->begin() + iNum); pDownloadQueue->GetFileQueue()->insert(pDownloadQueue->GetFileQueue()->begin() + iLastNum + 1, pFileInfo); iLastNum++; } else { iLastNum = iNum; } pLastFileInfo = pFileInfo; } iNum++; } }
bool PrePostProcessor::IsNZBFileCompleted(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo, bool bIgnorePausedPars, bool bAllowOnlyOneDeleted) { bool bNZBFileCompleted = true; int iDeleted = 0; for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++) { FileInfo* pFileInfo = *it; if (pFileInfo->GetNZBInfo() == pNZBInfo) { if (pFileInfo->GetDeleted()) { iDeleted++; } if (((!pFileInfo->GetPaused() || !bIgnorePausedPars || !(m_ParCoordinator.ParseParFilename(pFileInfo->GetFilename(), NULL, NULL))) && !pFileInfo->GetDeleted()) || (bAllowOnlyOneDeleted && iDeleted > 1)) { bNZBFileCompleted = false; break; } } } return bNZBFileCompleted; }
/** * Returns the first FileInfo belonging to given NZBInfo. */ FileInfo* PrePostProcessor::GetQueueGroup(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo) { for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++) { FileInfo* pFileInfo = *it; if (pFileInfo->GetNZBInfo() == pNZBInfo) { return pFileInfo; } } return NULL; }
NZBInfo* PrePostProcessor::MergeGroups(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo) { int iAddedGroupID = 0; // merge(1): find ID of any file in new nzb-file for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++) { FileInfo* pFileInfo = *it; if (pFileInfo->GetNZBInfo() == pNZBInfo) { iAddedGroupID = pFileInfo->GetID(); break; } } // merge(2): check if queue has other nzb-files with the same name if (iAddedGroupID > 0) { for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++) { FileInfo* pFileInfo = *it; if (pFileInfo->GetNZBInfo() != pNZBInfo && !strcmp(pFileInfo->GetNZBInfo()->GetName(), pNZBInfo->GetName())) { // file found, do merging IDList cIDList; cIDList.push_back(pFileInfo->GetID()); cIDList.push_back(iAddedGroupID); g_pQueueCoordinator->GetQueueEditor()->LockedEditList(pDownloadQueue, &cIDList, false, QueueEditor::eaGroupMerge, 0, NULL); return pFileInfo->GetNZBInfo(); } } } return pNZBInfo; }
void PrePostProcessor::NZBCompleted(DownloadQueue* pDownloadQueue, NZBInfo* pNZBInfo, bool bSaveQueue) { if (g_pOptions->GetKeepHistory() > 0) { //remove old item for the same NZB for (HistoryList::iterator it = pDownloadQueue->GetHistoryList()->begin(); it != pDownloadQueue->GetHistoryList()->end(); it++) { HistoryInfo* pHistoryInfo = *it; if (pHistoryInfo->GetNZBInfo() == pNZBInfo) { delete pHistoryInfo; pDownloadQueue->GetHistoryList()->erase(it); break; } } HistoryInfo* pHistoryInfo = new HistoryInfo(pNZBInfo); pHistoryInfo->SetTime(time(NULL)); pDownloadQueue->GetHistoryList()->push_front(pHistoryInfo); // park files int iParkedFiles = 0; int index = 0; for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); ) { FileInfo* pFileInfo = *it; if (pFileInfo->GetNZBInfo() == pNZBInfo && !pFileInfo->GetDeleted()) { detail("Park file %s", pFileInfo->GetFilename()); g_pQueueCoordinator->DiscardDiskFile(pFileInfo); pDownloadQueue->GetFileQueue()->erase(it); pDownloadQueue->GetParkedFiles()->push_back(pFileInfo); it = pDownloadQueue->GetFileQueue()->begin() + index; iParkedFiles++; } else { it++; index++; } } pNZBInfo->SetParkedFileCount(iParkedFiles); if (bSaveQueue) { SaveQueue(pDownloadQueue); } info("Collection %s added to history", pNZBInfo->GetName()); } }
void QueueEditor::ReorderFiles(DownloadQueue* pDownloadQueue, ItemList* pItemList) { if (pItemList->size() == 0) { return; } EditItem* pFirstItem = pItemList->front(); NZBInfo* pNZBInfo = pFirstItem->m_pFileInfo->GetNZBInfo(); unsigned int iInsertPos = 0; // find first file of the group for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++) { FileInfo* pFileInfo = *it; if (pFileInfo->GetNZBInfo() == pNZBInfo) { break; } iInsertPos++; } // now can reorder for (ItemList::iterator it = pItemList->begin(); it != pItemList->end(); it++) { EditItem* pItem = *it; FileInfo* pFileInfo = pItem->m_pFileInfo; // move file item for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++) { FileInfo* pFileInfo1 = *it; if (pFileInfo1 == pFileInfo) { pDownloadQueue->GetFileQueue()->erase(it); pDownloadQueue->GetFileQueue()->insert(pDownloadQueue->GetFileQueue()->begin() + iInsertPos, pFileInfo); iInsertPos++; break; } } delete pItem; } }
void QueueEditor::BuildGroupList(DownloadQueue* pDownloadQueue, FileList* pGroupList) { pGroupList->clear(); for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++) { FileInfo* pFileInfo = *it; FileInfo* pGroupInfo = NULL; for (FileList::iterator itg = pGroupList->begin(); itg != pGroupList->end(); itg++) { FileInfo* pGroupInfo1 = *itg; if (pGroupInfo1->GetNZBInfo() == pFileInfo->GetNZBInfo()) { pGroupInfo = pGroupInfo1; break; } } if (!pGroupInfo) { pGroupList->push_back(pFileInfo); } } }
void QueueEditor::PauseParsInGroups(ItemList* pItemList, bool bExtraParsOnly) { while (true) { FileList GroupFileList; GroupFileList.clear(); FileInfo* pFirstFileInfo = NULL; for (ItemList::iterator it = pItemList->begin(); it != pItemList->end(); ) { EditItem* pItem = *it; if (!pFirstFileInfo || (pFirstFileInfo->GetNZBInfo() == pItem->m_pFileInfo->GetNZBInfo())) { GroupFileList.push_back(pItem->m_pFileInfo); if (!pFirstFileInfo) { pFirstFileInfo = pItem->m_pFileInfo; } delete pItem; pItemList->erase(it); it = pItemList->begin(); continue; } it++; } if (!GroupFileList.empty()) { PausePars(&GroupFileList, bExtraParsOnly); } else { break; } } }
void PrePostProcessor::HistoryDelete(DownloadQueue* pDownloadQueue, HistoryList::iterator itHistory, HistoryInfo* pHistoryInfo) { char szNiceName[1024]; pHistoryInfo->GetName(szNiceName, 1024); info("Deleting %s from history", szNiceName); if (pHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo) { NZBInfo* pNZBInfo = pHistoryInfo->GetNZBInfo(); // delete parked files int index = 0; for (FileQueue::iterator it = pDownloadQueue->GetParkedFiles()->begin(); it != pDownloadQueue->GetParkedFiles()->end(); ) { FileInfo* pFileInfo = *it; if (pFileInfo->GetNZBInfo() == pNZBInfo) { pDownloadQueue->GetParkedFiles()->erase(it); if (g_pOptions->GetSaveQueue() && g_pOptions->GetServerMode()) { g_pDiskState->DiscardFile(pFileInfo); } delete pFileInfo; it = pDownloadQueue->GetParkedFiles()->begin() + index; } else { it++; index++; } } } pDownloadQueue->GetHistoryList()->erase(itHistory); delete pHistoryInfo; }
void PrePostProcessor::HistoryReturn(DownloadQueue* pDownloadQueue, HistoryList::iterator itHistory, HistoryInfo* pHistoryInfo, bool bReprocess) { char szNiceName[1024]; pHistoryInfo->GetName(szNiceName, 1024); debug("Returning %s from history back to download queue", szNiceName); bool bUnparked = false; if (bReprocess && pHistoryInfo->GetKind() != HistoryInfo::hkNZBInfo) { error("Could not restart postprocessing for %s: history item has wrong type", szNiceName); return; } if (pHistoryInfo->GetKind() == HistoryInfo::hkNZBInfo) { NZBInfo* pNZBInfo = pHistoryInfo->GetNZBInfo(); // unpark files int index = 0; for (FileQueue::reverse_iterator it = pDownloadQueue->GetParkedFiles()->rbegin(); it != pDownloadQueue->GetParkedFiles()->rend(); ) { FileInfo* pFileInfo = *it; if (pFileInfo->GetNZBInfo() == pNZBInfo) { detail("Unpark file %s", pFileInfo->GetFilename()); pDownloadQueue->GetParkedFiles()->erase(pDownloadQueue->GetParkedFiles()->end() - 1 - index); pDownloadQueue->GetFileQueue()->push_front(pFileInfo); bUnparked = true; it = pDownloadQueue->GetParkedFiles()->rbegin() + index; } else { it++; index++; } } // reset postprocessing status variables pNZBInfo->SetPostProcess(false); pNZBInfo->SetParCleanup(false); if (!pNZBInfo->GetUnpackCleanedUpDisk()) { pNZBInfo->SetParStatus(NZBInfo::psNone); pNZBInfo->SetRenameStatus(NZBInfo::rsNone); pNZBInfo->SetUnpackStatus(NZBInfo::usNone); pNZBInfo->SetCleanupStatus(NZBInfo::csNone); } pNZBInfo->GetScriptStatuses()->Clear(); pNZBInfo->SetParkedFileCount(0); } if (pHistoryInfo->GetKind() == HistoryInfo::hkUrlInfo) { UrlInfo* pUrlInfo = pHistoryInfo->GetUrlInfo(); pHistoryInfo->DiscardUrlInfo(); pUrlInfo->SetStatus(UrlInfo::aiUndefined); pDownloadQueue->GetUrlQueue()->push_back(pUrlInfo); bUnparked = true; } if (bUnparked || bReprocess) { pDownloadQueue->GetHistoryList()->erase(itHistory); // the object "pHistoryInfo" is released few lines later, after the call to "NZBDownloaded" info("%s returned from history back to download queue", szNiceName); } else { warn("Could not return %s back from history to download queue: history item does not have any files left for download", szNiceName); } if (bReprocess) { // start postprocessing debug("Restarting postprocessing for %s", szNiceName); NZBDownloaded(pDownloadQueue, pHistoryInfo->GetNZBInfo()); } if (bUnparked || bReprocess) { delete pHistoryInfo; } }
void ListBinCommand::Execute() { SNZBListRequest ListRequest; if (!ReceiveRequest(&ListRequest, sizeof(ListRequest))) { return; } SNZBListResponse ListResponse; memset(&ListResponse, 0, sizeof(ListResponse)); ListResponse.m_MessageBase.m_iSignature = htonl(NZBMESSAGE_SIGNATURE); ListResponse.m_MessageBase.m_iStructSize = htonl(sizeof(ListResponse)); ListResponse.m_iEntrySize = htonl(sizeof(SNZBListResponseFileEntry)); ListResponse.m_bRegExValid = 0; char* buf = NULL; int bufsize = 0; if (ntohl(ListRequest.m_bFileList)) { eRemoteMatchMode eMatchMode = (eRemoteMatchMode)ntohl(ListRequest.m_iMatchMode); bool bMatchGroup = ntohl(ListRequest.m_bMatchGroup); const char* szPattern = ListRequest.m_szPattern; RegEx *pRegEx = NULL; if (eMatchMode == eRemoteMatchModeRegEx) { pRegEx = new RegEx(szPattern); ListResponse.m_bRegExValid = pRegEx->IsValid(); } // 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 iNrNZBEntries = pDownloadQueue->GetNZBInfoList()->size(); int iNrPPPEntries = 0; bufsize += iNrNZBEntries * sizeof(SNZBListResponseNZBEntry); for (NZBInfoList::iterator it = pDownloadQueue->GetNZBInfoList()->begin(); it != pDownloadQueue->GetNZBInfoList()->end(); it++) { NZBInfo* pNZBInfo = *it; bufsize += strlen(pNZBInfo->GetFilename()) + 1; bufsize += strlen(pNZBInfo->GetName()) + 1; bufsize += strlen(pNZBInfo->GetDestDir()) + 1; bufsize += strlen(pNZBInfo->GetCategory()) + 1; bufsize += strlen(pNZBInfo->GetQueuedFilename()) + 1; // align struct to 4-bytes, needed by ARM-processor (and may be others) bufsize += bufsize % 4 > 0 ? 4 - bufsize % 4 : 0; // calculate required buffer size for pp-parameters for (NZBParameterList::iterator it = pNZBInfo->GetParameters()->begin(); it != pNZBInfo->GetParameters()->end(); it++) { NZBParameter* pNZBParameter = *it; bufsize += sizeof(SNZBListResponsePPPEntry); bufsize += strlen(pNZBParameter->GetName()) + 1; bufsize += strlen(pNZBParameter->GetValue()) + 1; // align struct to 4-bytes, needed by ARM-processor (and may be others) bufsize += bufsize % 4 > 0 ? 4 - bufsize % 4 : 0; iNrPPPEntries++; } } // calculate required buffer size for files int iNrFileEntries = pDownloadQueue->GetFileQueue()->size(); bufsize += iNrFileEntries * sizeof(SNZBListResponseFileEntry); for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++) { FileInfo* pFileInfo = *it; bufsize += strlen(pFileInfo->GetSubject()) + 1; bufsize += strlen(pFileInfo->GetFilename()) + 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 (NZBInfoList::iterator it = pDownloadQueue->GetNZBInfoList()->begin(); it != pDownloadQueue->GetNZBInfoList()->end(); it++) { unsigned long iSizeHi, iSizeLo; NZBInfo* pNZBInfo = *it; SNZBListResponseNZBEntry* pListAnswer = (SNZBListResponseNZBEntry*) bufptr; Util::SplitInt64(pNZBInfo->GetSize(), &iSizeHi, &iSizeLo); pListAnswer->m_iSizeLo = htonl(iSizeLo); pListAnswer->m_iSizeHi = htonl(iSizeHi); pListAnswer->m_bMatch = htonl(bMatchGroup && (!pRegEx || pRegEx->Match(pNZBInfo->GetName()))); pListAnswer->m_iFilenameLen = htonl(strlen(pNZBInfo->GetFilename()) + 1); pListAnswer->m_iNameLen = htonl(strlen(pNZBInfo->GetName()) + 1); pListAnswer->m_iDestDirLen = htonl(strlen(pNZBInfo->GetDestDir()) + 1); pListAnswer->m_iCategoryLen = htonl(strlen(pNZBInfo->GetCategory()) + 1); pListAnswer->m_iQueuedFilenameLen = htonl(strlen(pNZBInfo->GetQueuedFilename()) + 1); bufptr += sizeof(SNZBListResponseNZBEntry); strcpy(bufptr, pNZBInfo->GetFilename()); bufptr += ntohl(pListAnswer->m_iFilenameLen); strcpy(bufptr, pNZBInfo->GetName()); bufptr += ntohl(pListAnswer->m_iNameLen); strcpy(bufptr, pNZBInfo->GetDestDir()); bufptr += ntohl(pListAnswer->m_iDestDirLen); strcpy(bufptr, pNZBInfo->GetCategory()); bufptr += ntohl(pListAnswer->m_iCategoryLen); strcpy(bufptr, pNZBInfo->GetQueuedFilename()); bufptr += ntohl(pListAnswer->m_iQueuedFilenameLen); // align struct to 4-bytes, needed by ARM-processor (and may be others) if ((size_t)bufptr % 4 > 0) { pListAnswer->m_iQueuedFilenameLen = htonl(ntohl(pListAnswer->m_iQueuedFilenameLen) + 4 - (size_t)bufptr % 4); memset(bufptr, 0, 4 - (size_t)bufptr % 4); //suppress valgrind warning "uninitialized data" bufptr += 4 - (size_t)bufptr % 4; } } // write ppp entries int iNZBIndex = 1; for (NZBInfoList::iterator it = pDownloadQueue->GetNZBInfoList()->begin(); it != pDownloadQueue->GetNZBInfoList()->end(); it++, iNZBIndex++) { NZBInfo* pNZBInfo = *it; for (NZBParameterList::iterator it = pNZBInfo->GetParameters()->begin(); it != pNZBInfo->GetParameters()->end(); it++) { NZBParameter* pNZBParameter = *it; SNZBListResponsePPPEntry* pListAnswer = (SNZBListResponsePPPEntry*) bufptr; pListAnswer->m_iNZBIndex = htonl(iNZBIndex); pListAnswer->m_iNameLen = htonl(strlen(pNZBParameter->GetName()) + 1); pListAnswer->m_iValueLen = htonl(strlen(pNZBParameter->GetValue()) + 1); bufptr += sizeof(SNZBListResponsePPPEntry); strcpy(bufptr, pNZBParameter->GetName()); bufptr += ntohl(pListAnswer->m_iNameLen); strcpy(bufptr, pNZBParameter->GetValue()); bufptr += ntohl(pListAnswer->m_iValueLen); // align struct to 4-bytes, needed by ARM-processor (and may be others) if ((size_t)bufptr % 4 > 0) { pListAnswer->m_iValueLen = htonl(ntohl(pListAnswer->m_iValueLen) + 4 - (size_t)bufptr % 4); memset(bufptr, 0, 4 - (size_t)bufptr % 4); //suppress valgrind warning "uninitialized data" bufptr += 4 - (size_t)bufptr % 4; } } } // write file entries for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++) { unsigned long iSizeHi, iSizeLo; FileInfo* pFileInfo = *it; SNZBListResponseFileEntry* pListAnswer = (SNZBListResponseFileEntry*) bufptr; pListAnswer->m_iID = htonl(pFileInfo->GetID()); int iNZBIndex = 0; for (unsigned int i = 0; i < pDownloadQueue->GetNZBInfoList()->size(); i++) { iNZBIndex++; if (pDownloadQueue->GetNZBInfoList()->at(i) == pFileInfo->GetNZBInfo()) { break; } } pListAnswer->m_iNZBIndex = htonl(iNZBIndex); if (pRegEx && !bMatchGroup) { char szFilename[MAX_PATH]; snprintf(szFilename, sizeof(szFilename) - 1, "%s/%s", pFileInfo->GetNZBInfo()->GetName(), Util::BaseFileName(pFileInfo->GetFilename())); pListAnswer->m_bMatch = htonl(pRegEx->Match(szFilename)); } Util::SplitInt64(pFileInfo->GetSize(), &iSizeHi, &iSizeLo); pListAnswer->m_iFileSizeLo = htonl(iSizeLo); pListAnswer->m_iFileSizeHi = htonl(iSizeHi); Util::SplitInt64(pFileInfo->GetRemainingSize(), &iSizeHi, &iSizeLo); pListAnswer->m_iRemainingSizeLo = htonl(iSizeLo); pListAnswer->m_iRemainingSizeHi = htonl(iSizeHi); pListAnswer->m_bFilenameConfirmed = htonl(pFileInfo->GetFilenameConfirmed()); pListAnswer->m_bPaused = htonl(pFileInfo->GetPaused()); pListAnswer->m_iActiveDownloads = htonl(pFileInfo->GetActiveDownloads()); pListAnswer->m_iPriority = htonl(pFileInfo->GetPriority()); pListAnswer->m_iSubjectLen = htonl(strlen(pFileInfo->GetSubject()) + 1); pListAnswer->m_iFilenameLen = htonl(strlen(pFileInfo->GetFilename()) + 1); bufptr += sizeof(SNZBListResponseFileEntry); strcpy(bufptr, pFileInfo->GetSubject()); bufptr += ntohl(pListAnswer->m_iSubjectLen); strcpy(bufptr, pFileInfo->GetFilename()); bufptr += ntohl(pListAnswer->m_iFilenameLen); // align struct to 4-bytes, needed by ARM-processor (and may be others) if ((size_t)bufptr % 4 > 0) { pListAnswer->m_iFilenameLen = htonl(ntohl(pListAnswer->m_iFilenameLen) + 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(); if (pRegEx) { delete pRegEx; } ListResponse.m_iNrTrailingNZBEntries = htonl(iNrNZBEntries); ListResponse.m_iNrTrailingPPPEntries = htonl(iNrPPPEntries); ListResponse.m_iNrTrailingFileEntries = htonl(iNrFileEntries); ListResponse.m_iTrailingDataLength = htonl(bufsize); } if (htonl(ListRequest.m_bServerState)) { unsigned long iSizeHi, iSizeLo; ListResponse.m_iDownloadRate = htonl((int)(g_pQueueCoordinator->CalcCurrentDownloadSpeed() * 1024)); Util::SplitInt64(g_pQueueCoordinator->CalcRemainingSize(), &iSizeHi, &iSizeLo); ListResponse.m_iRemainingSizeHi = htonl(iSizeHi); ListResponse.m_iRemainingSizeLo = htonl(iSizeLo); ListResponse.m_iDownloadLimit = htonl((int)(g_pOptions->GetDownloadRate() * 1024)); ListResponse.m_bDownloadPaused = htonl(g_pOptions->GetPauseDownload()); ListResponse.m_bDownload2Paused = htonl(g_pOptions->GetPauseDownload2()); ListResponse.m_bPostPaused = htonl(g_pOptions->GetPausePostProcess()); ListResponse.m_bScanPaused = htonl(g_pOptions->GetPauseScan()); ListResponse.m_iThreadCount = htonl(Thread::GetThreadCount() - 1); // not counting itself PostQueue* pPostQueue = g_pQueueCoordinator->LockQueue()->GetPostQueue(); ListResponse.m_iPostJobCount = htonl(pPostQueue->size()); g_pQueueCoordinator->UnlockQueue(); int iUpTimeSec, iDnTimeSec; long long iAllBytes; bool bStandBy; g_pQueueCoordinator->CalcStat(&iUpTimeSec, &iDnTimeSec, &iAllBytes, &bStandBy); ListResponse.m_iUpTimeSec = htonl(iUpTimeSec); ListResponse.m_iDownloadTimeSec = htonl(iDnTimeSec); ListResponse.m_bDownloadStandBy = htonl(bStandBy); Util::SplitInt64(iAllBytes, &iSizeHi, &iSizeLo); ListResponse.m_iDownloadedBytesHi = htonl(iSizeHi); ListResponse.m_iDownloadedBytesLo = htonl(iSizeLo); } // Send the request answer send(m_iSocket, (char*) &ListResponse, sizeof(ListResponse), 0); // Send the data if (bufsize > 0) { send(m_iSocket, buf, bufsize, 0); } if (buf) { free(buf); } }
bool QueueEditor::EditGroup(DownloadQueue* pDownloadQueue, FileInfo* pFileInfo, EEditAction eAction, int iOffset, const char* szText) { IDList cIDList; cIDList.clear(); // collecting files belonging to group for (FileQueue::iterator it = pDownloadQueue->GetFileQueue()->begin(); it != pDownloadQueue->GetFileQueue()->end(); it++) { FileInfo* pFileInfo2 = *it; if (pFileInfo2->GetNZBInfo() == pFileInfo->GetNZBInfo()) { cIDList.push_back(pFileInfo2->GetID()); } } if (eAction == eaGroupMoveOffset) { // calculating offset in terms of files FileList cGroupList; BuildGroupList(pDownloadQueue, &cGroupList); unsigned int iNum = 0; for (FileList::iterator it = cGroupList.begin(); it != cGroupList.end(); it++, iNum++) { FileInfo* pGroupInfo = *it; if (pGroupInfo->GetNZBInfo() == pFileInfo->GetNZBInfo()) { break; } } int iFileOffset = 0; if (iOffset > 0) { if (iNum + iOffset >= cGroupList.size() - 1) { eAction = eaGroupMoveBottom; } else { for (unsigned int i = iNum + 2; i < cGroupList.size() && iOffset > 0; i++, iOffset--) { iFileOffset += FindFileInfoEntry(pDownloadQueue, cGroupList[i]) - FindFileInfoEntry(pDownloadQueue, cGroupList[i-1]); } } } else { if (iNum + iOffset <= 0) { eAction = eaGroupMoveTop; } else { for (unsigned int i = iNum; i > 0 && iOffset < 0; i--, iOffset++) { iFileOffset -= FindFileInfoEntry(pDownloadQueue, cGroupList[i]) - FindFileInfoEntry(pDownloadQueue, cGroupList[i-1]); } } } iOffset = iFileOffset; } else if (eAction == eaGroupDelete) { pFileInfo->GetNZBInfo()->SetDeleted(true); pFileInfo->GetNZBInfo()->SetCleanupDisk(CanCleanupDisk(pDownloadQueue, pFileInfo->GetNZBInfo())); } EEditAction GroupToFileMap[] = { (EEditAction)0, eaFileMoveOffset, eaFileMoveTop, eaFileMoveBottom, eaFilePause, eaFileResume, eaFileDelete, eaFilePauseAllPars, eaFilePauseExtraPars, eaFileSetPriority, eaFileReorder, eaFileMoveOffset, eaFileMoveTop, eaFileMoveBottom, eaFilePause, eaFileResume, eaFileDelete, eaFilePauseAllPars, eaFilePauseExtraPars, eaFileSetPriority, (EEditAction)0, (EEditAction)0, (EEditAction)0 }; return InternEditList(pDownloadQueue, &cIDList, true, GroupToFileMap[eAction], iOffset, szText); }
/* * 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; }
void QueueEditor::AlignAffectedGroups(DownloadQueue* pDownloadQueue, IDList* pIDList, bool bSmartOrder, int iOffset) { // Build list of all groups; List contains first file of each group FileList cGroupList; BuildGroupList(pDownloadQueue, &cGroupList); // Find affected groups. It includes groups being moved and groups directly // above or under of these groups (those order is also changed) FileList cAffectedGroupList; cAffectedGroupList.clear(); ItemList cItemList; PrepareList(pDownloadQueue, &cItemList, pIDList, bSmartOrder, eaFileMoveOffset, iOffset); for (ItemList::iterator it = cItemList.begin(); it != cItemList.end(); it++) { EditItem* pItem = *it; unsigned int iNum = 0; for (FileList::iterator it = cGroupList.begin(); it != cGroupList.end(); it++, iNum++) { FileInfo* pFileInfo = *it; if (pItem->m_pFileInfo->GetNZBInfo() == pFileInfo->GetNZBInfo()) { if (!ItemExists(&cAffectedGroupList, pFileInfo)) { cAffectedGroupList.push_back(pFileInfo); } if (iOffset < 0) { for (int i = iNum - 1; i >= -iOffset-1; i--) { if (!ItemExists(&cAffectedGroupList, cGroupList[i])) { cAffectedGroupList.push_back(cGroupList[i]); } } } if (iOffset > 0) { for (unsigned int i = iNum + 1; i <= cGroupList.size() - iOffset; i++) { if (!ItemExists(&cAffectedGroupList, cGroupList[i])) { cAffectedGroupList.push_back(cGroupList[i]); } } if (iNum + 1 < cGroupList.size()) { cAffectedGroupList.push_back(cGroupList[iNum + 1]); } } break; } } delete pItem; } cGroupList.clear(); // Aligning groups for (FileList::iterator it = cAffectedGroupList.begin(); it != cAffectedGroupList.end(); it++) { FileInfo* pFileInfo = *it; AlignGroup(pDownloadQueue, pFileInfo->GetNZBInfo()); } }
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(); }
bool QueueEditor::BuildIDListFromNameList(DownloadQueue* pDownloadQueue, IDList* pIDList, NameList* pNameList, EMatchMode eMatchMode, EEditAction eAction) { #ifndef HAVE_REGEX_H if (eMatchMode == mmRegEx) { return false; } #endif std::set<int> uniqueIDs; for (NameList::iterator it = pNameList->begin(); it != pNameList->end(); it++) { const char* szName = *it; RegEx *pRegEx = NULL; if (eMatchMode == mmRegEx) { pRegEx = new RegEx(szName); if (!pRegEx->IsValid()) { delete pRegEx; return false; } } bool bFound = false; for (FileQueue::iterator it2 = pDownloadQueue->GetFileQueue()->begin(); it2 != pDownloadQueue->GetFileQueue()->end(); it2++) { FileInfo* pFileInfo = *it2; if (eAction < eaGroupMoveOffset) { // file action char szFilename[MAX_PATH]; snprintf(szFilename, sizeof(szFilename) - 1, "%s/%s", pFileInfo->GetNZBInfo()->GetName(), Util::BaseFileName(pFileInfo->GetFilename())); if (((!pRegEx && !strcmp(szFilename, szName)) || (pRegEx && pRegEx->Match(szFilename))) && (uniqueIDs.find(pFileInfo->GetID()) == uniqueIDs.end())) { uniqueIDs.insert(pFileInfo->GetID()); pIDList->push_back(pFileInfo->GetID()); bFound = true; } } else { // group action const char *szFilename = pFileInfo->GetNZBInfo()->GetName(); if (((!pRegEx && !strcmp(szFilename, szName)) || (pRegEx && pRegEx->Match(szFilename))) && (uniqueIDs.find(pFileInfo->GetNZBInfo()->GetID()) == uniqueIDs.end())) { uniqueIDs.insert(pFileInfo->GetNZBInfo()->GetID()); pIDList->push_back(pFileInfo->GetID()); bFound = true; } } } if (pRegEx) { delete pRegEx; } if (!bFound && (eMatchMode == mmName)) { return false; } } return true; }