/* * This file is part of nzbget. See . * * Copyright (C) 2004 Sven Henkel * Copyright (C) 2007-2019 Andrey Prygunkov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DOWNLOADINFO_H #define DOWNLOADINFO_H #include "NString.h" #include "Container.h" #include "Observer.h" #include "Log.h" #include "Thread.h" class NzbInfo; class DownloadQueue; class PostInfo; class ServerStat { public: ServerStat(int serverId) : m_serverId(serverId) {} int GetServerId() { return m_serverId; } int GetSuccessArticles() { return m_successArticles; } void SetSuccessArticles(int successArticles) { m_successArticles = successArticles; } int GetFailedArticles() { return m_failedArticles; } void SetFailedArticles(int failedArticles) { m_failedArticles = failedArticles; } private: int m_serverId; int m_successArticles = 0; int m_failedArticles = 0; }; typedef std::vector ServerStatListBase; class ServerStatList : public ServerStatListBase { public: enum EStatOperation { soSet, soAdd, soSubtract }; void StatOp(int serverId, int successArticles, int failedArticles, EStatOperation statOperation); void ListOp(ServerStatList* serverStats, EStatOperation statOperation); }; class SegmentData { public: virtual char* GetData() = 0; virtual ~SegmentData() {} }; class ArticleInfo { public: enum EStatus { aiUndefined, aiRunning, aiFinished, aiFailed }; void SetPartNumber(int s) { m_partNumber = s; } int GetPartNumber() { return m_partNumber; } const char* GetMessageId() { return m_messageId; } void SetMessageId(const char* messageId) { m_messageId = messageId; } void SetSize(int size) { m_size = size; } int GetSize() { return m_size; } void AttachSegment(std::unique_ptr content, int64 offset, int size); void DiscardSegment(); const char* GetSegmentContent() { return m_segmentContent ? m_segmentContent->GetData() : nullptr; } void SetSegmentOffset(int64 segmentOffset) { m_segmentOffset = segmentOffset; } int64 GetSegmentOffset() { return m_segmentOffset; } void SetSegmentSize(int segmentSize) { m_segmentSize = segmentSize; } int GetSegmentSize() { return m_segmentSize; } EStatus GetStatus() { return m_status; } void SetStatus(EStatus Status) { m_status = Status; } const char* GetResultFilename() { return m_resultFilename; } void SetResultFilename(const char* resultFilename) { m_resultFilename = resultFilename; } uint32 GetCrc() { return m_crc; } void SetCrc(uint32 crc) { m_crc = crc; } private: int m_partNumber; CString m_messageId; int m_size = 0; std::unique_ptr m_segmentContent; int64 m_segmentOffset = 0; int m_segmentSize = 0; EStatus m_status = aiUndefined; CString m_resultFilename; uint32 m_crc = 0; }; typedef std::vector> ArticleList; class FileInfo { public: enum EPartialState { psNone, psPartial, psCompleted }; typedef std::vector Groups; FileInfo(int id = 0) : m_id(id ? id : ++m_idGen) {} int GetId() { return m_id; } void SetId(int id); static void ResetGenId(bool max); NzbInfo* GetNzbInfo() { return m_nzbInfo; } void SetNzbInfo(NzbInfo* nzbInfo) { m_nzbInfo = nzbInfo; } ArticleList* GetArticles() { return &m_articles; } Groups* GetGroups() { return &m_groups; } const char* GetSubject() { return m_subject; } void SetSubject(const char* subject) { m_subject = subject; } const char* GetFilename() { return m_filename; } void SetFilename(const char* filename) { m_filename = filename; } void SetOrigname(const char* origname) { m_origname = origname; } const char* GetOrigname() { return m_origname; } void MakeValidFilename(); bool GetFilenameConfirmed() { return m_filenameConfirmed; } void SetFilenameConfirmed(bool filenameConfirmed) { m_filenameConfirmed = filenameConfirmed; } void SetSize(int64 size) { m_size = size; m_remainingSize = size; } int64 GetSize() { return m_size; } int64 GetRemainingSize() { return m_remainingSize; } void SetRemainingSize(int64 remainingSize) { m_remainingSize = remainingSize; } int64 GetMissedSize() { return m_missedSize; } void SetMissedSize(int64 missedSize) { m_missedSize = missedSize; } int64 GetSuccessSize() { return m_successSize; } void SetSuccessSize(int64 successSize) { m_successSize = successSize; } int64 GetFailedSize() { return m_failedSize; } void SetFailedSize(int64 failedSize) { m_failedSize = failedSize; } int GetTotalArticles() { return m_totalArticles; } void SetTotalArticles(int totalArticles) { m_totalArticles = totalArticles; } int GetMissedArticles() { return m_missedArticles; } void SetMissedArticles(int missedArticles) { m_missedArticles = missedArticles; } int GetFailedArticles() { return m_failedArticles; } void SetFailedArticles(int failedArticles) { m_failedArticles = failedArticles; } int GetSuccessArticles() { return m_successArticles; } void SetSuccessArticles(int successArticles) { m_successArticles = successArticles; } time_t GetTime() { return m_time; } void SetTime(time_t time) { m_time = time; } bool GetPaused() { return m_paused; } void SetPaused(bool paused); bool GetDeleted() { return m_deleted; } void SetDeleted(bool Deleted) { m_deleted = Deleted; } int GetCompletedArticles() { return m_completedArticles; } void SetCompletedArticles(int completedArticles) { m_completedArticles = completedArticles; } bool GetParFile() { return m_parFile; } void SetParFile(bool parFile) { m_parFile = parFile; } Guard GuardOutputFile() { return Guard(m_outputFileMutex); } const char* GetOutputFilename() { return m_outputFilename; } void SetOutputFilename(const char* outputFilename) { m_outputFilename = outputFilename; } bool GetOutputInitialized() { return m_outputInitialized; } void SetOutputInitialized(bool outputInitialized) { m_outputInitialized = outputInitialized; } bool GetExtraPriority() { return m_extraPriority; } void SetExtraPriority(bool extraPriority); int GetActiveDownloads() { return m_activeDownloads; } void SetActiveDownloads(int activeDownloads); bool GetDupeDeleted() { return m_dupeDeleted; } void SetDupeDeleted(bool dupeDeleted) { m_dupeDeleted = dupeDeleted; } int GetCachedArticles() { return m_cachedArticles; } void SetCachedArticles(int cachedArticles) { m_cachedArticles = cachedArticles; } bool GetPartialChanged() { return m_partialChanged; } void SetPartialChanged(bool partialChanged) { m_partialChanged = partialChanged; } bool GetForceDirectWrite() { return m_forceDirectWrite; } void SetForceDirectWrite(bool forceDirectWrite) { m_forceDirectWrite = forceDirectWrite; } EPartialState GetPartialState() { return m_partialState; } void SetPartialState(EPartialState partialState) { m_partialState = partialState; } uint32 GetCrc() { return m_crc; } void SetCrc(uint32 crc) { m_crc = crc; } const char* GetHash16k() { return m_hash16k; } void SetHash16k(const char* hash16k) { m_hash16k = hash16k; } const char* GetParSetId() { return m_parSetId; } void SetParSetId(const char* parSetId) { m_parSetId = parSetId; } bool GetFlushLocked() { return m_flushLocked; } void SetFlushLocked(bool flushLocked) { m_flushLocked = flushLocked; } ServerStatList* GetServerStats() { return &m_serverStats; } private: int m_id; NzbInfo* m_nzbInfo = nullptr; ArticleList m_articles; Groups m_groups; ServerStatList m_serverStats; CString m_subject; CString m_filename; CString m_origname; int64 m_size = 0; int64 m_remainingSize = 0; int64 m_successSize = 0; int64 m_failedSize = 0; int64 m_missedSize = 0; int m_totalArticles = 0; int m_missedArticles = 0; int m_failedArticles = 0; int m_successArticles = 0; time_t m_time = 0; bool m_paused = false; bool m_deleted = false; bool m_filenameConfirmed = false; bool m_parFile = false; int m_completedArticles = 0; bool m_outputInitialized = false; CString m_outputFilename; std::unique_ptr m_outputFileMutex; bool m_extraPriority = false; int m_activeDownloads = 0; bool m_dupeDeleted = false; int m_cachedArticles = 0; bool m_partialChanged = false; bool m_forceDirectWrite = false; EPartialState m_partialState = psNone; uint32 m_crc = 0; CString m_hash16k; CString m_parSetId; bool m_flushLocked = false; static int m_idGen; static int m_idMax; friend class CompletedFile; }; typedef UniqueDeque FileList; typedef std::vector RawFileList; class CompletedFile { public: enum EStatus { cfNone, cfSuccess, cfPartial, cfFailure }; CompletedFile(int id, const char* filename, const char* oldname, EStatus status, uint32 crc, bool parFile, const char* hash16k, const char* parSetId); int GetId() { return m_id; } void SetFilename(const char* filename) { m_filename = filename; } const char* GetFilename() { return m_filename; } void SetOrigname(const char* origname) { m_origname = origname; } const char* GetOrigname() { return m_origname; } bool GetParFile() { return m_parFile; } EStatus GetStatus() { return m_status; } uint32 GetCrc() { return m_crc; } const char* GetHash16k() { return m_hash16k; } void SetHash16k(const char* hash16k) { m_hash16k = hash16k; } const char* GetParSetId() { return m_parSetId; } void SetParSetId(const char* parSetId) { m_parSetId = parSetId; } private: int m_id; CString m_filename; CString m_origname; EStatus m_status; uint32 m_crc; bool m_parFile; CString m_hash16k; CString m_parSetId; }; typedef std::deque CompletedFileList; class NzbParameter { public: NzbParameter(const char* name, const char* value) : m_name(name), m_value(value) {} const char* GetName() { return m_name; } const char* GetValue() { return m_value; } private: CString m_name; CString m_value; void SetValue(const char* value) { m_value = value; } friend class NzbParameterList; }; typedef std::deque NzbParameterListBase; class NzbParameterList : public NzbParameterListBase { public: void SetParameter(const char* name, const char* value); NzbParameter* Find(const char* name); void CopyFrom(NzbParameterList* sourceParameters); }; class ScriptStatus { public: enum EStatus { srNone, srFailure, srSuccess }; ScriptStatus(const char* name, EStatus status) : m_name(name), m_status(status) {} const char* GetName() { return m_name; } EStatus GetStatus() { return m_status; } private: CString m_name; EStatus m_status; friend class ScriptStatusList; }; typedef std::deque ScriptStatusListBase; class ScriptStatusList : public ScriptStatusListBase { public: ScriptStatus::EStatus CalcTotalStatus(); }; enum EDupeMode { dmScore, dmAll, dmForce }; class NzbInfo { public: enum EDirectRenameStatus { tsNone, tsRunning, tsFailure, tsSuccess }; enum EPostRenameStatus { rsNone, rsSkipped, rsNothing, rsSuccess }; enum EParStatus { psNone, psSkipped, psFailure, psSuccess, psRepairPossible, psManual }; enum EDirectUnpackStatus { nsNone, nsRunning, nsFailure, nsSuccess }; enum EPostUnpackStatus { usNone, usSkipped, usFailure, usSuccess, usSpace, usPassword }; enum ECleanupStatus { csNone, csFailure, csSuccess }; enum EMoveStatus { msNone, msFailure, msSuccess }; enum EDeleteStatus { dsNone, dsManual, dsHealth, dsDupe, dsBad, dsGood, dsCopy, dsScan }; enum EMarkStatus { ksNone, ksBad, ksGood, ksSuccess }; enum EUrlStatus { lsNone, lsRunning, lsFinished, lsFailed, lsRetry, lsScanSkipped, lsScanFailed }; enum EKind { nkNzb, nkUrl }; enum EDupeHint { dhNone, dhRedownloadManual, dhRedownloadAuto }; int GetId() { return m_id; } void SetId(int id); static void ResetGenId(bool max); static int GenerateId(); EKind GetKind() { return m_kind; } void SetKind(EKind kind) { m_kind = kind; } const char* GetUrl() { return m_url; } void SetUrl(const char* url); const char* GetFilename() { return m_filename; } void SetFilename(const char* filename); static CString MakeNiceNzbName(const char* nzbFilename, bool removeExt); static CString MakeNiceUrlName(const char* url, const char* nzbFilename); const char* GetDestDir() { return m_destDir; } void SetDestDir(const char* destDir) { m_destDir = destDir; } const char* GetFinalDir() { return m_finalDir; } void SetFinalDir(const char* finalDir) { m_finalDir = finalDir; } const char* GetCategory() { return m_category; } void SetCategory(const char* category) { m_category = category; } const char* GetName() { return m_name; } void SetName(const char* name) { m_name = name; } int GetFileCount() { return m_fileCount; } void SetFileCount(int fileCount) { m_fileCount = fileCount; } int GetParkedFileCount() { return m_parkedFileCount; } void SetParkedFileCount(int parkedFileCount) { m_parkedFileCount = parkedFileCount; } int64 GetSize() { return m_size; } void SetSize(int64 size) { m_size = size; } int64 GetRemainingSize() { return m_remainingSize; } void SetRemainingSize(int64 remainingSize) { m_remainingSize = remainingSize; } int64 GetPausedSize() { return m_pausedSize; } void SetPausedSize(int64 pausedSize) { m_pausedSize = pausedSize; } int GetPausedFileCount() { return m_pausedFileCount; } void SetPausedFileCount(int pausedFileCount) { m_pausedFileCount = pausedFileCount; } int GetRemainingParCount() { return m_remainingParCount; } void SetRemainingParCount(int remainingParCount) { m_remainingParCount = remainingParCount; } int GetActiveDownloads() { return m_activeDownloads; } void SetActiveDownloads(int activeDownloads); int64 GetSuccessSize() { return m_successSize; } void SetSuccessSize(int64 successSize) { m_successSize = successSize; } int64 GetFailedSize() { return m_failedSize; } void SetFailedSize(int64 failedSize) { m_failedSize = failedSize; } int64 GetCurrentSuccessSize() { return m_currentSuccessSize; } void SetCurrentSuccessSize(int64 currentSuccessSize) { m_currentSuccessSize = currentSuccessSize; } int64 GetCurrentFailedSize() { return m_currentFailedSize; } void SetCurrentFailedSize(int64 currentFailedSize) { m_currentFailedSize = currentFailedSize; } int64 GetParSize() { return m_parSize; } void SetParSize(int64 parSize) { m_parSize = parSize; } int64 GetParSuccessSize() { return m_parSuccessSize; } void SetParSuccessSize(int64 parSuccessSize) { m_parSuccessSize = parSuccessSize; } int64 GetParFailedSize() { return m_parFailedSize; } void SetParFailedSize(int64 parFailedSize) { m_parFailedSize = parFailedSize; } int64 GetParCurrentSuccessSize() { return m_parCurrentSuccessSize; } void SetParCurrentSuccessSize(int64 parCurrentSuccessSize) { m_parCurrentSuccessSize = parCurrentSuccessSize; } int64 GetParCurrentFailedSize() { return m_parCurrentFailedSize; } void SetParCurrentFailedSize(int64 parCurrentFailedSize) { m_parCurrentFailedSize = parCurrentFailedSize; } int GetTotalArticles() { return m_totalArticles; } void SetTotalArticles(int totalArticles) { m_totalArticles = totalArticles; } int GetSuccessArticles() { return m_successArticles; } void SetSuccessArticles(int successArticles) { m_successArticles = successArticles; } int GetFailedArticles() { return m_failedArticles; } void SetFailedArticles(int failedArticles) { m_failedArticles = failedArticles; } int GetCurrentSuccessArticles() { return m_currentSuccessArticles; } void SetCurrentSuccessArticles(int currentSuccessArticles) { m_currentSuccessArticles = currentSuccessArticles; } int GetCurrentFailedArticles() { return m_currentFailedArticles; } void SetCurrentFailedArticles(int currentFailedArticles) { m_currentFailedArticles = currentFailedArticles; } int GetPriority() { return m_priority; } void SetPriority(int priority) { m_priority = priority; } int GetExtraPriority() { return m_extraPriority; } void SetExtraPriority(int extraPriority) { m_extraPriority = extraPriority; } bool HasExtraPriority() { return m_extraPriority > 0; } bool GetForcePriority() { return m_priority >= FORCE_PRIORITY; } time_t GetMinTime() { return m_minTime; } void SetMinTime(time_t minTime) { m_minTime = minTime; } time_t GetMaxTime() { return m_maxTime; } void SetMaxTime(time_t maxTime) { m_maxTime = maxTime; } void BuildDestDirName(); CString BuildFinalDirName(); CompletedFileList* GetCompletedFiles() { return &m_completedFiles; } void SetDirectRenameStatus(EDirectRenameStatus renameStatus) { m_directRenameStatus = renameStatus; } EDirectRenameStatus GetDirectRenameStatus() { return m_directRenameStatus; } EPostRenameStatus GetParRenameStatus() { return m_parRenameStatus; } void SetParRenameStatus(EPostRenameStatus renameStatus) { m_parRenameStatus = renameStatus; } EPostRenameStatus GetRarRenameStatus() { return m_rarRenameStatus; } void SetRarRenameStatus(EPostRenameStatus renameStatus) { m_rarRenameStatus = renameStatus; } EParStatus GetParStatus() { return m_parStatus; } void SetParStatus(EParStatus parStatus) { m_parStatus = parStatus; } EDirectUnpackStatus GetDirectUnpackStatus() { return m_directUnpackStatus; } void SetDirectUnpackStatus(EDirectUnpackStatus directUnpackStatus) { m_directUnpackStatus = directUnpackStatus; } EPostUnpackStatus GetUnpackStatus() { return m_unpackStatus; } void SetUnpackStatus(EPostUnpackStatus unpackStatus) { m_unpackStatus = unpackStatus; } ECleanupStatus GetCleanupStatus() { return m_cleanupStatus; } void SetCleanupStatus(ECleanupStatus cleanupStatus) { m_cleanupStatus = cleanupStatus; } EMoveStatus GetMoveStatus() { return m_moveStatus; } void SetMoveStatus(EMoveStatus moveStatus) { m_moveStatus = moveStatus; } EDeleteStatus GetDeleteStatus() { return m_deleteStatus; } void SetDeleteStatus(EDeleteStatus deleteStatus) { m_deleteStatus = deleteStatus; } EMarkStatus GetMarkStatus() { return m_markStatus; } void SetMarkStatus(EMarkStatus markStatus) { m_markStatus = markStatus; } EUrlStatus GetUrlStatus() { return m_urlStatus; } int GetExtraParBlocks() { return m_extraParBlocks; } void SetExtraParBlocks(int extraParBlocks) { m_extraParBlocks = extraParBlocks; } void SetUrlStatus(EUrlStatus urlStatus) { m_urlStatus = urlStatus; } const char* GetQueuedFilename() { return m_queuedFilename; } void SetQueuedFilename(const char* queuedFilename) { m_queuedFilename = queuedFilename; } bool GetDeleting() { return m_deleting; } void SetDeleting(bool deleting) { m_deleting = deleting; } bool GetParking() { return m_parking; } void SetParking(bool parking) { m_parking = parking; } bool GetDeletePaused() { return m_deletePaused; } void SetDeletePaused(bool deletePaused) { m_deletePaused = deletePaused; } bool GetManyDupeFiles() { return m_manyDupeFiles; } void SetManyDupeFiles(bool manyDupeFiles) { m_manyDupeFiles = manyDupeFiles; } bool GetAvoidHistory() { return m_avoidHistory; } void SetAvoidHistory(bool avoidHistory) { m_avoidHistory = avoidHistory; } bool GetHealthPaused() { return m_healthPaused; } void SetHealthPaused(bool healthPaused) { m_healthPaused = healthPaused; } bool GetCleanupDisk() { return m_cleanupDisk; } void SetCleanupDisk(bool cleanupDisk) { m_cleanupDisk = cleanupDisk; } bool GetUnpackCleanedUpDisk() { return m_unpackCleanedUpDisk; } void SetUnpackCleanedUpDisk(bool unpackCleanedUpDisk) { m_unpackCleanedUpDisk = unpackCleanedUpDisk; } bool GetAddUrlPaused() { return m_addUrlPaused; } void SetAddUrlPaused(bool addUrlPaused) { m_addUrlPaused = addUrlPaused; } FileList* GetFileList() { return &m_fileList; } NzbParameterList* GetParameters() { return &m_ppParameters; } ScriptStatusList* GetScriptStatuses() { return &m_scriptStatuses; } ServerStatList* GetServerStats() { return &m_serverStats; } ServerStatList* GetCurrentServerStats() { return &m_currentServerStats; } int CalcHealth(); int CalcCriticalHealth(bool allowEstimation); const char* GetDupeKey() { return m_dupeKey; } void SetDupeKey(const char* dupeKey) { m_dupeKey = dupeKey ? dupeKey : ""; } int GetDupeScore() { return m_dupeScore; } void SetDupeScore(int dupeScore) { m_dupeScore = dupeScore; } EDupeMode GetDupeMode() { return m_dupeMode; } void SetDupeMode(EDupeMode dupeMode) { m_dupeMode = dupeMode; } EDupeHint GetDupeHint() { return m_dupeHint; } void SetDupeHint(EDupeHint dupeHint) { m_dupeHint = dupeHint; } uint32 GetFullContentHash() { return m_fullContentHash; } void SetFullContentHash(uint32 fullContentHash) { m_fullContentHash = fullContentHash; } uint32 GetFilteredContentHash() { return m_filteredContentHash; } void SetFilteredContentHash(uint32 filteredContentHash) { m_filteredContentHash = filteredContentHash; } int64 GetDownloadedSize() { return m_downloadedSize; } void SetDownloadedSize(int64 downloadedSize) { m_downloadedSize = downloadedSize; } int GetDownloadSec() { return m_downloadSec; } void SetDownloadSec(int downloadSec) { m_downloadSec = downloadSec; } int GetPostTotalSec() { return m_postTotalSec; } void SetPostTotalSec(int postTotalSec) { m_postTotalSec = postTotalSec; } int GetParSec() { return m_parSec; } void SetParSec(int parSec) { m_parSec = parSec; } int GetRepairSec() { return m_repairSec; } void SetRepairSec(int repairSec) { m_repairSec = repairSec; } int GetUnpackSec() { return m_unpackSec; } void SetUnpackSec(int unpackSec) { m_unpackSec = unpackSec; } time_t GetDownloadStartTime() { return m_downloadStartTime; } void SetDownloadStartTime(time_t downloadStartTime) { m_downloadStartTime = downloadStartTime; } bool GetChanged() { return m_changed; } void SetChanged(bool changed) { m_changed = changed; } void SetReprocess(bool reprocess) { m_reprocess = reprocess; } bool GetReprocess() { return m_reprocess; } time_t GetQueueScriptTime() { return m_queueScriptTime; } void SetQueueScriptTime(time_t queueScriptTime) { m_queueScriptTime = queueScriptTime; } void SetParFull(bool parFull) { m_parFull = parFull; } bool GetParFull() { return m_parFull; } int GetFeedId() { return m_feedId; } void SetFeedId(int feedId) { m_feedId = feedId; } void MoveFileList(NzbInfo* srcNzbInfo); void UpdateMinMaxTime(); PostInfo* GetPostInfo() { return m_postInfo.get(); } void EnterPostProcess(); void LeavePostProcess(); bool IsDupeSuccess(); const char* MakeTextStatus(bool ignoreScriptStatus); void AddMessage(Message::EKind kind, const char* text, bool print = true); void PrintMessage(Message::EKind kind, const char* format, ...) PRINTF_SYNTAX(3); int GetMessageCount() { return m_messageCount; } void SetMessageCount(int messageCount) { m_messageCount = messageCount; } int GetCachedMessageCount() { return m_cachedMessageCount; } GuardedMessageList GuardCachedMessages() { return GuardedMessageList(&m_messages, &m_logMutex); } bool GetAllFirst() { return m_allFirst; } void SetAllFirst(bool allFirst) { m_allFirst = allFirst; } bool GetWaitingPar() { return m_waitingPar; } void SetWaitingPar(bool waitingPar) { m_waitingPar = waitingPar; } bool GetLoadingPar() { return m_loadingPar; } void SetLoadingPar(bool loadingPar) { m_loadingPar = loadingPar; } Thread* GetUnpackThread() { return m_unpackThread; } void SetUnpackThread(Thread* unpackThread) { m_unpackThread = unpackThread; } void UpdateCurrentStats(); void UpdateCompletedStats(FileInfo* fileInfo); void UpdateDeletedStats(FileInfo* fileInfo); bool IsDownloadCompleted(bool ignorePausedPars); static const int FORCE_PRIORITY = 900; private: int m_id = ++m_idGen; EKind m_kind = nkNzb; CString m_url = ""; CString m_filename = ""; CString m_name; CString m_destDir = ""; CString m_finalDir = ""; CString m_category = ""; int m_fileCount = 0; int m_parkedFileCount = 0; int64 m_size = 0; int64 m_remainingSize = 0; int m_pausedFileCount = 0; int64 m_pausedSize = 0; int m_remainingParCount = 0; int m_activeDownloads = 0; int64 m_successSize = 0; int64 m_failedSize = 0; int64 m_currentSuccessSize = 0; int64 m_currentFailedSize = 0; int64 m_parSize = 0; int64 m_parSuccessSize = 0; int64 m_parFailedSize = 0; int64 m_parCurrentSuccessSize = 0; int64 m_parCurrentFailedSize = 0; int m_totalArticles = 0; int m_successArticles = 0; int m_failedArticles = 0; int m_currentSuccessArticles = 0; int m_currentFailedArticles = 0; time_t m_minTime = 0; time_t m_maxTime = 0; int m_priority = 0; int m_extraPriority = 0; CompletedFileList m_completedFiles; EDirectRenameStatus m_directRenameStatus = tsNone; EPostRenameStatus m_parRenameStatus = rsNone; EPostRenameStatus m_rarRenameStatus = rsNone; EParStatus m_parStatus = psNone; EDirectUnpackStatus m_directUnpackStatus = nsNone; EPostUnpackStatus m_unpackStatus = usNone; ECleanupStatus m_cleanupStatus = csNone; EMoveStatus m_moveStatus = msNone; EDeleteStatus m_deleteStatus = dsNone; EMarkStatus m_markStatus = ksNone; EUrlStatus m_urlStatus = lsNone; int m_extraParBlocks = 0; bool m_addUrlPaused = false; bool m_deletePaused = false; bool m_manyDupeFiles = false; CString m_queuedFilename = ""; bool m_deleting = false; bool m_parking = false; bool m_avoidHistory = false; bool m_healthPaused = false; bool m_parManual = false; bool m_cleanupDisk = false; bool m_unpackCleanedUpDisk = false; CString m_dupeKey = ""; int m_dupeScore = 0; EDupeMode m_dupeMode = dmScore; EDupeHint m_dupeHint = dhNone; uint32 m_fullContentHash = 0; uint32 m_filteredContentHash = 0; FileList m_fileList; NzbParameterList m_ppParameters; ScriptStatusList m_scriptStatuses; ServerStatList m_serverStats; ServerStatList m_currentServerStats; Mutex m_logMutex; MessageList m_messages; int m_idMessageGen = 0; std::unique_ptr m_postInfo; int64 m_downloadedSize = 0; time_t m_downloadStartTime = 0; int m_downloadStartSec = 0; int m_downloadSec = 0; int m_postTotalSec = 0; int m_parSec = 0; int m_repairSec = 0; int m_unpackSec = 0; bool m_reprocess = false; bool m_changed = false; time_t m_queueScriptTime = 0; bool m_parFull = false; int m_messageCount = 0; int m_cachedMessageCount = 0; int m_feedId = 0; bool m_allFirst = false; bool m_waitingPar = false; bool m_loadingPar = false; Thread* m_unpackThread = nullptr; static int m_idGen; static int m_idMax; void ClearMessages(); friend class DupInfo; }; typedef UniqueDeque NzbList; typedef std::vector RawNzbList; class PostInfo { public: enum EStage { ptQueued, ptLoadingPars, ptVerifyingSources, ptRepairing, ptVerifyingRepaired, ptParRenaming, ptRarRenaming, ptUnpacking, ptCleaningUp, ptMoving, ptExecutingScript, ptFinished }; typedef std::vector ParredFiles; typedef std::vector ExtractedArchives; NzbInfo* GetNzbInfo() { return m_nzbInfo; } void SetNzbInfo(NzbInfo* nzbInfo) { m_nzbInfo = nzbInfo; } EStage GetStage() { return m_stage; } void SetStage(EStage stage) { m_stage = stage; } void SetProgressLabel(const char* progressLabel) { m_progressLabel = progressLabel; } const char* GetProgressLabel() { return m_progressLabel; } int GetFileProgress() { return m_fileProgress; } void SetFileProgress(int fileProgress) { m_fileProgress = fileProgress; } int GetStageProgress() { return m_stageProgress; } void SetStageProgress(int stageProgress) { m_stageProgress = stageProgress; } time_t GetStartTime() { return m_startTime; } void SetStartTime(time_t startTime) { m_startTime = startTime; } time_t GetStageTime() { return m_stageTime; } void SetStageTime(time_t stageTime) { m_stageTime = stageTime; } bool GetWorking() { return m_working; } void SetWorking(bool working) { m_working = working; } bool GetDeleted() { return m_deleted; } void SetDeleted(bool deleted) { m_deleted = deleted; } bool GetRequestParCheck() { return m_requestParCheck; } void SetRequestParCheck(bool requestParCheck) { m_requestParCheck = requestParCheck; } bool GetForceParFull() { return m_forceParFull; } void SetForceParFull(bool forceParFull) { m_forceParFull = forceParFull; } bool GetForceRepair() { return m_forceRepair; } void SetForceRepair(bool forceRepair) { m_forceRepair = forceRepair; } bool GetParRepaired() { return m_parRepaired; } void SetParRepaired(bool parRepaired) { m_parRepaired = parRepaired; } bool GetUnpackTried() { return m_unpackTried; } void SetUnpackTried(bool unpackTried) { m_unpackTried = unpackTried; } bool GetPassListTried() { return m_passListTried; } void SetPassListTried(bool passListTried) { m_passListTried = passListTried; } int GetLastUnpackStatus() { return m_lastUnpackStatus; } void SetLastUnpackStatus(int unpackStatus) { m_lastUnpackStatus = unpackStatus; } bool GetNeedParCheck() { return m_needParCheck; } void SetNeedParCheck(bool needParCheck) { m_needParCheck = needParCheck; } Thread* GetPostThread() { return m_postThread; } void SetPostThread(Thread* postThread) { m_postThread = postThread; } ParredFiles* GetParredFiles() { return &m_parredFiles; } ExtractedArchives* GetExtractedArchives() { return &m_extractedArchives; } private: NzbInfo* m_nzbInfo = nullptr; bool m_working = false; bool m_deleted = false; bool m_requestParCheck = false; bool m_forceParFull = false; bool m_forceRepair = false; bool m_parRepaired = false; bool m_unpackTried = false; bool m_passListTried = false; int m_lastUnpackStatus = 0; bool m_needParCheck = false; EStage m_stage = ptQueued; CString m_progressLabel = ""; int m_fileProgress = 0; int m_stageProgress = 0; time_t m_startTime = 0; time_t m_stageTime = 0; Thread* m_postThread = nullptr; ParredFiles m_parredFiles; ExtractedArchives m_extractedArchives; }; typedef std::vector IdList; typedef std::vector NameList; class DupInfo { public: enum EStatus { dsUndefined, dsSuccess, dsFailed, dsDeleted, dsDupe, dsBad, dsGood }; int GetId() { return m_id; } void SetId(int id); const char* GetName() { return m_name; } void SetName(const char* name) { m_name = name; } const char* GetDupeKey() { return m_dupeKey; } void SetDupeKey(const char* dupeKey) { m_dupeKey = dupeKey; } int GetDupeScore() { return m_dupeScore; } void SetDupeScore(int dupeScore) { m_dupeScore = dupeScore; } EDupeMode GetDupeMode() { return m_dupeMode; } void SetDupeMode(EDupeMode dupeMode) { m_dupeMode = dupeMode; } int64 GetSize() { return m_size; } void SetSize(int64 size) { m_size = size; } uint32 GetFullContentHash() { return m_fullContentHash; } void SetFullContentHash(uint32 fullContentHash) { m_fullContentHash = fullContentHash; } uint32 GetFilteredContentHash() { return m_filteredContentHash; } void SetFilteredContentHash(uint32 filteredContentHash) { m_filteredContentHash = filteredContentHash; } EStatus GetStatus() { return m_status; } void SetStatus(EStatus Status) { m_status = Status; } private: int m_id = 0; CString m_name; CString m_dupeKey; int m_dupeScore = 0; EDupeMode m_dupeMode = dmScore; int64 m_size = 0; uint32 m_fullContentHash = 0; uint32 m_filteredContentHash = 0; EStatus m_status = dsUndefined; }; class HistoryInfo { public: enum EKind { hkUnknown, hkNzb, hkUrl, hkDup }; HistoryInfo(std::unique_ptr nzbInfo) : m_info(nzbInfo.release()), m_kind(GetNzbInfo()->GetKind() == NzbInfo::nkNzb ? hkNzb : hkUrl) {} HistoryInfo(std::unique_ptr dupInfo) : m_info(dupInfo.release()), m_kind(hkDup) {} ~HistoryInfo(); EKind GetKind() { return m_kind; } int GetId(); NzbInfo* GetNzbInfo() { return (NzbInfo*)m_info; } DupInfo* GetDupInfo() { return (DupInfo*)m_info; } void DiscardNzbInfo() { m_info = nullptr; } time_t GetTime() { return m_time; } void SetTime(time_t time) { m_time = time; } const char* GetName(); private: void* m_info; EKind m_kind; time_t m_time = 0; }; typedef UniqueDeque HistoryList; typedef GuardedPtr GuardedDownloadQueue; class DownloadQueue : public Subject { public: enum EAspectAction { eaNzbFound, eaNzbAdded, eaNzbDeleted, eaNzbNamed, eaNzbReturned, eaFileCompleted, eaFileDeleted, eaUrlFound, eaUrlAdded, eaUrlDeleted, eaUrlCompleted, eaUrlFailed, eaUrlReturned }; struct Aspect { EAspectAction action; DownloadQueue* downloadQueue; NzbInfo* nzbInfo; FileInfo* fileInfo; }; enum EEditAction { eaFileMoveOffset = 1, // move files to m_iOffset relative to the current position in download-queue eaFileMoveTop, // move files to the top of download-queue eaFileMoveBottom, // move files to the bottom of download-queue eaFilePause, // pause files eaFileResume, // resume (unpause) files eaFileDelete, // delete files eaFilePauseAllPars, // pause only (all) pars (does not affect other files) eaFilePauseExtraPars, // pause (almost all) pars, except main par-file (does not affect other files) eaFileReorder, // set file order eaFileSplit, // split - create new group from selected files eaGroupMoveOffset, // move group to offset relative to the current position in download-queue eaGroupMoveTop, // move group to the top of download-queue eaGroupMoveBottom, // move group to the bottom of download-queue eaGroupMoveBefore, // move group to a certain position eaGroupMoveAfter, // move group to a certain position eaGroupPause, // pause group eaGroupResume, // resume (unpause) group eaGroupDelete, // delete group and put to history, delete already downloaded files eaGroupParkDelete, // delete group and put to history, keep already downloaded files eaGroupDupeDelete, // delete group, put to history and mark as duplicate, delete already downloaded files eaGroupFinalDelete, // delete group without adding to history, delete already downloaded files eaGroupPauseAllPars, // pause only (all) pars (does not affect other files) in group eaGroupPauseExtraPars, // pause only (almost all) pars in group, except main par-file (does not affect other files) eaGroupSetPriority, // set priority for groups eaGroupSetCategory, // set or change category for a group eaGroupApplyCategory, // set or change category for a group and reassign pp-params according to category settings eaGroupMerge, // merge groups eaGroupSetParameter, // set post-process parameter for group eaGroupSetName, // set group name (rename group) eaGroupSetDupeKey, // set duplicate key eaGroupSetDupeScore, // set duplicate score eaGroupSetDupeMode, // set duplicate mode eaGroupSort, // sort groups eaGroupSortFiles, // sort files for optimal download order eaPostDelete, // cancel post-processing eaHistoryDelete, // hide history-item eaHistoryFinalDelete, // delete history-item eaHistoryReturn, // move history-item back to download queue eaHistoryProcess, // move history-item back to download queue and start postprocessing eaHistoryRedownload, // move history-item back to download queue for full redownload eaHistoryRetryFailed, // move history-item back to download queue for redownload of failed articles eaHistorySetParameter, // set post-process parameter for history-item eaHistorySetDupeKey, // set duplicate key eaHistorySetDupeScore, // set duplicate score eaHistorySetDupeMode, // set duplicate mode eaHistorySetDupeBackup, // set duplicate backup flag eaHistoryMarkBad, // mark history-item as bad (and download other duplicate) eaHistoryMarkGood, // mark history-item as good (and push it into dup-history) eaHistoryMarkSuccess, // mark history-item as success (and do nothing more) eaHistorySetCategory, // set or change category for history-item eaHistorySetName // set history-item name (rename) }; enum EMatchMode { mmId = 1, mmName, mmRegEx }; static bool IsLoaded() { return g_Loaded; } static GuardedDownloadQueue Guard() { return GuardedDownloadQueue(g_DownloadQueue, &g_DownloadQueue->m_lockMutex); } NzbList* GetQueue() { return &m_queue; } HistoryList* GetHistory() { return &m_history; } virtual bool EditEntry(int ID, EEditAction action, const char* args) = 0; virtual bool EditList(IdList* idList, NameList* nameList, EMatchMode matchMode, EEditAction action, const char* args) = 0; virtual void HistoryChanged() = 0; virtual void Save() = 0; virtual void SaveChanged() = 0; void CalcRemainingSize(int64* remaining, int64* remainingForced); protected: DownloadQueue() {} static void Init(DownloadQueue* globalInstance) { g_DownloadQueue = globalInstance; } static void Final() { g_DownloadQueue = nullptr; } static void Loaded() { g_Loaded = true; } private: NzbList m_queue; HistoryList m_history; Mutex m_lockMutex; static DownloadQueue* g_DownloadQueue; static bool g_Loaded; }; #endif