Files
nzbget/daemon/queue/DownloadInfo.h
Andrey Prygunkov 3a5bc85962 #351: notify about url or nzb returned to queue
from history.
2019-01-26 21:09:48 +01:00

1043 lines
36 KiB
C++

/*
* This file is part of nzbget. See <http://nzbget.net>.
*
* Copyright (C) 2004 Sven Henkel <sidddy@users.sourceforge.net>
* Copyright (C) 2007-2019 Andrey Prygunkov <hugbug@users.sourceforge.net>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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<ServerStat> 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<SegmentData> 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<SegmentData> m_segmentContent;
int64 m_segmentOffset = 0;
int m_segmentSize = 0;
EStatus m_status = aiUndefined;
CString m_resultFilename;
uint32 m_crc = 0;
};
typedef std::vector<std::unique_ptr<ArticleInfo>> ArticleList;
class FileInfo
{
public:
enum EPartialState
{
psNone,
psPartial,
psCompleted
};
typedef std::vector<CString> 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<Mutex> 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<FileInfo> FileList;
typedef std::vector<FileInfo*> 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<CompletedFile> 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<NzbParameter> 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<ScriptStatus> 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<PostInfo> 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<NzbInfo> NzbList;
typedef std::vector<NzbInfo*> RawNzbList;
class PostInfo
{
public:
enum EStage
{
ptQueued,
ptLoadingPars,
ptVerifyingSources,
ptRepairing,
ptVerifyingRepaired,
ptParRenaming,
ptRarRenaming,
ptUnpacking,
ptCleaningUp,
ptMoving,
ptExecutingScript,
ptFinished
};
typedef std::vector<CString> ParredFiles;
typedef std::vector<CString> 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<int> IdList;
typedef std::vector<CString> 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> nzbInfo) : m_info(nzbInfo.release()),
m_kind(GetNzbInfo()->GetKind() == NzbInfo::nkNzb ? hkNzb : hkUrl) {}
HistoryInfo(std::unique_ptr<DupInfo> 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<HistoryInfo> HistoryList;
typedef GuardedPtr<DownloadQueue> 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