diff --git a/PostInfo.cpp b/PostInfo.cpp index 92290b86..ae00dfa4 100644 --- a/PostInfo.cpp +++ b/PostInfo.cpp @@ -36,6 +36,9 @@ #include "nzbget.h" #include "PostInfo.h" +#include "Options.h" + +extern Options* g_pOptions; PostInfo::PostInfo() { @@ -53,6 +56,8 @@ PostInfo::PostInfo() m_tStartTime = 0; m_tStageTime = 0; m_eStage = ptQueued; + m_Messages.clear(); + m_iIDGen = 0; } PostInfo::~ PostInfo() @@ -77,6 +82,11 @@ PostInfo::~ PostInfo() { free(m_szProgressLabel); } + for (Messages::iterator it = m_Messages.begin(); it != m_Messages.end(); it++) + { + delete *it; + } + m_Messages.clear(); } void PostInfo::SetNZBFilename(const char* szNZBFilename) @@ -108,3 +118,29 @@ void PostInfo::SetProgressLabel(const char* szProgressLabel) m_szProgressLabel = strdup(szProgressLabel); } +PostInfo::Messages* PostInfo::LockMessages() +{ + m_mutexLog.Lock(); + return &m_Messages; +} + +void PostInfo::UnlockMessages() +{ + m_mutexLog.Unlock(); +} + +void PostInfo::AppendMessage(Message::EKind eKind, const char * szText) +{ + Message* pMessage = new Message(++m_iIDGen, eKind, time(NULL), szText); + + m_mutexLog.Lock(); + m_Messages.push_back(pMessage); + + while (m_Messages.size() > (unsigned int)g_pOptions->GetLogBufferSize()) + { + Message* pMessage = m_Messages.front(); + delete pMessage; + m_Messages.pop_front(); + } + m_mutexLog.Unlock(); +} diff --git a/PostInfo.h b/PostInfo.h index be65f046..14bf7131 100644 --- a/PostInfo.h +++ b/PostInfo.h @@ -28,6 +28,8 @@ #include +#include "Log.h" + class PostInfo { public: @@ -42,6 +44,8 @@ public: ptFinished }; + typedef std::deque Messages; + private: char* m_szNZBFilename; char* m_szDestDir; @@ -58,6 +62,10 @@ private: time_t m_tStartTime; time_t m_tStageTime; + Mutex m_mutexLog; + Messages m_Messages; + unsigned int m_iIDGen; + public: PostInfo(); ~PostInfo(); @@ -89,6 +97,9 @@ public: void SetParStatus(int iParStatus) { m_iParStatus = iParStatus; } bool GetParFailed() { return m_bParFailed; } void SetParFailed(bool bParFailed) { m_bParFailed = bParFailed; } + void AppendMessage(Message::EKind eKind, const char* szText); + Messages* LockMessages(); + void UnlockMessages(); }; typedef std::deque PostQueue; diff --git a/ScriptController.cpp b/ScriptController.cpp index 2ce71b22..e922d713 100644 --- a/ScriptController.cpp +++ b/ScriptController.cpp @@ -258,25 +258,52 @@ void ScriptController::AddMessage(char* szText) if (!strncmp(szText, "[INFO] ", 7)) { info(szText + 7); + Options::EMessageTarget eMessageTarget = g_pOptions->GetInfoTarget(); + if (eMessageTarget == Options::mtScreen || eMessageTarget == Options::mtBoth) + { + m_pPostInfo->AppendMessage(Message::mkInfo, szText + 7); + } } else if (!strncmp(szText, "[WARNING] ", 10)) { warn(szText + 10); + Options::EMessageTarget eMessageTarget = g_pOptions->GetWarningTarget(); + if (eMessageTarget == Options::mtScreen || eMessageTarget == Options::mtBoth) + { + m_pPostInfo->AppendMessage(Message::mkWarning, szText + 10); + } } else if (!strncmp(szText, "[ERROR] ", 8)) { error(szText + 8); + Options::EMessageTarget eMessageTarget = g_pOptions->GetErrorTarget(); + if (eMessageTarget == Options::mtScreen || eMessageTarget == Options::mtBoth) + { + m_pPostInfo->AppendMessage(Message::mkError, szText + 8); + } } else if (!strncmp(szText, "[DETAIL] ", 9)) { detail(szText + 9); + Options::EMessageTarget eMessageTarget = g_pOptions->GetDetailTarget(); + if (eMessageTarget == Options::mtScreen || eMessageTarget == Options::mtBoth) + { + m_pPostInfo->AppendMessage(Message::mkDetail, szText + 9); + } } else if (!strncmp(szText, "[DEBUG] ", 8)) { debug(szText + 8); + Options::EMessageTarget eMessageTarget = g_pOptions->GetDebugTarget(); + if (eMessageTarget == Options::mtScreen || eMessageTarget == Options::mtBoth) + { + m_pPostInfo->AppendMessage(Message::mkDebug, szText + 8); + } } else { + Options::EMessageTarget eMessageTarget = Options::mtNone; + Message::EKind eKind = Message::mkDebug; switch (g_pOptions->GetPostLogKind()) { case Options::plNone: @@ -284,23 +311,37 @@ void ScriptController::AddMessage(char* szText) case Options::plDetail: detail("Post-Process: %s", szText); + eMessageTarget = g_pOptions->GetDetailTarget(); + eKind = Message::mkDetail; break; case Options::plInfo: info("Post-Process: %s", szText); + eMessageTarget = g_pOptions->GetInfoTarget(); + eKind = Message::mkInfo; break; case Options::plWarning: warn("Post-Process: %s", szText); + eMessageTarget = g_pOptions->GetWarningTarget(); + eKind = Message::mkWarning; break; case Options::plError: error("Post-Process: %s", szText); + eMessageTarget = g_pOptions->GetErrorTarget(); + eKind = Message::mkError; break; case Options::plDebug: debug("Post-Process: %s", szText); + eMessageTarget = g_pOptions->GetDebugTarget(); + eKind = Message::mkDebug; break; } + if (eMessageTarget == Options::mtScreen || eMessageTarget == Options::mtBoth) + { + m_pPostInfo->AppendMessage(eKind, szText); + } } } diff --git a/XmlRpc.cpp b/XmlRpc.cpp index 822065b8..3b647249 100644 --- a/XmlRpc.cpp +++ b/XmlRpc.cpp @@ -1243,9 +1243,12 @@ void DownloadXmlCommand::Execute() void PostQueueXmlCommand::Execute() { + int iNrEntries = 0; + NextParamAsInt(&iNrEntries); + AppendResponse(IsJson() ? "[\n" : "\n"); - const char* XML_POSTQUEUE_ITEM = + const char* XML_POSTQUEUE_ITEM_START = "\n" "NZBNicename%s\n" "NZBFilename%s\n" @@ -1258,9 +1261,13 @@ void PostQueueXmlCommand::Execute() "StageProgress%i\n" "TotalTimeSec%i\n" "StageTimeSec%i\n" + "Log\n"; + + const char* XML_POSTQUEUE_ITEM_END = + "\n" "\n"; - const char* JSON_POSTQUEUE_ITEM = + const char* JSON_POSTQUEUE_ITEM_START = "{\n" "\"NZBNicename\" : \"%s\",\n" "\"NZBFilename\" : \"%s\",\n" @@ -1272,7 +1279,27 @@ void PostQueueXmlCommand::Execute() "\"FileProgress\" : %i,\n" "\"StageProgress\" : %i,\n" "\"TotalTimeSec\" : %i,\n" - "\"StageTimeSec\" : %i\n" + "\"StageTimeSec\" : %i,\n" + "\"Log\" : [\n"; + + const char* JSON_POSTQUEUE_ITEM_END = + "]\n" + "}"; + + const char* XML_LOG_ITEM = + "\n" + "ID%i\n" + "Kind%s\n" + "Time%i\n" + "Text%s\n" + "\n"; + + const char* JSON_LOG_ITEM = + "{\n" + "\"ID\" : %i,\n" + "\"Kind\" : \"%s\",\n" + "\"Time\" : %i,\n" + "\"Text\" : \"%s\"\n" "}"; PostQueue* pPostQueue = g_pPrePostProcessor->LockPostQueue(); @@ -1297,7 +1324,7 @@ void PostQueueXmlCommand::Execute() char* xmlInfoName = EncodeStr(pPostInfo->GetInfoName()); char* xmlProgressLabel = EncodeStr(pPostInfo->GetProgressLabel()); - snprintf(szItemBuf, szItemBufSize, IsJson() ? JSON_POSTQUEUE_ITEM : XML_POSTQUEUE_ITEM, + snprintf(szItemBuf, szItemBufSize, IsJson() ? JSON_POSTQUEUE_ITEM_START : XML_POSTQUEUE_ITEM_START, xmlNZBNicename, xmlNZBFilename, xmlDestDir, xmlParFilename, xmlInfoName, szPostStageName[pPostInfo->GetStage()], xmlProgressLabel, pPostInfo->GetFileProgress(), pPostInfo->GetStageProgress(), @@ -1317,6 +1344,42 @@ void PostQueueXmlCommand::Execute() AppendResponse(",\n"); } AppendResponse(szItemBuf); + + if (iNrEntries > 0) + { + PostInfo::Messages* pMessages = pPostInfo->LockMessages(); + if (!pMessages->empty()) + { + int iStart = pMessages->size(); + if (iNrEntries > (int)pMessages->size()) + { + iNrEntries = pMessages->size(); + } + iStart = pMessages->size() - iNrEntries; + + char* szMessageType[] = { "INFO", "WARNING", "ERROR", "DEBUG", "DETAIL"}; + int index = 0; + + for (unsigned int i = (unsigned int)iStart; i < pMessages->size(); i++) + { + Message* pMessage = (*pMessages)[i]; + char* xmltext = EncodeStr(pMessage->GetText()); + snprintf(szItemBuf, szItemBufSize, IsJson() ? JSON_LOG_ITEM : XML_LOG_ITEM, + pMessage->GetID(), szMessageType[pMessage->GetKind()], pMessage->GetTime(), xmltext); + szItemBuf[szItemBufSize-1] = '\0'; + free(xmltext); + + if (IsJson() && index++ > 0) + { + AppendResponse(",\n"); + } + AppendResponse(szItemBuf); + } + } + pPostInfo->UnlockMessages(); + } + + AppendResponse(IsJson() ? JSON_POSTQUEUE_ITEM_END : XML_POSTQUEUE_ITEM_END); } free(szItemBuf);