Files
nzbget/daemon/frontend/Frontend.cpp
Andrey Prygunkov f3f7fbd0de #176: updated copyright notice in source files
- added link to http://nzbget.net;
- replaced FSF Post address with a web link;
- removed unusable subversion-tags;
- updated year.
2016-03-01 19:45:07 +01:00

339 lines
8.4 KiB
C++

/*
* This file is part of nzbget. See <http://nzbget.net>.
*
* Copyright (C) 2004 Sven Henkel <sidddy@users.sourceforge.net>
* Copyright (C) 2007-2016 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/>.
*/
#include "nzbget.h"
#include "Options.h"
#include "Frontend.h"
#include "Log.h"
#include "Connection.h"
#include "MessageBase.h"
#include "RemoteClient.h"
#include "Util.h"
#include "StatMeter.h"
Frontend::Frontend()
{
debug("Creating Frontend");
m_updateInterval = g_Options->GetUpdateInterval();
}
bool Frontend::PrepareData()
{
if (IsRemoteMode())
{
if (IsStopped())
{
return false;
}
if (!RequestMessages() || ((m_summary || m_fileList) && !RequestFileList()))
{
const char* controlIp = !strcmp(g_Options->GetControlIp(), "0.0.0.0") ? "127.0.0.1" : g_Options->GetControlIp();
printf("\nUnable to send request to nzbget-server at %s (port %i) \n", controlIp, g_Options->GetControlPort());
Stop();
return false;
}
}
else
{
if (m_summary)
{
m_currentDownloadSpeed = g_StatMeter->CalcCurrentDownloadSpeed();
m_pauseDownload = g_Options->GetPauseDownload();
m_downloadLimit = g_Options->GetDownloadRate();
m_threadCount = Thread::GetThreadCount();
g_StatMeter->CalcTotalStat(&m_upTimeSec, &m_dnTimeSec, &m_allBytes, &m_standBy);
DownloadQueue *downloadQueue = DownloadQueue::Lock();
m_postJobCount = 0;
for (NzbInfo* nzbInfo : downloadQueue->GetQueue())
{
m_postJobCount += nzbInfo->GetPostInfo() ? 1 : 0;
}
downloadQueue->CalcRemainingSize(&m_remainingSize, nullptr);
DownloadQueue::Unlock();
}
}
return true;
}
void Frontend::FreeData()
{
if (IsRemoteMode())
{
m_remoteMessages.clear();
DownloadQueue* downloadQueue = DownloadQueue::Lock();
downloadQueue->GetQueue()->Clear();
DownloadQueue::Unlock();
}
}
MessageList* Frontend::LockMessages()
{
if (IsRemoteMode())
{
return &m_remoteMessages;
}
else
{
return g_Log->LockMessages();
}
}
void Frontend::UnlockMessages()
{
if (!IsRemoteMode())
{
g_Log->UnlockMessages();
}
}
DownloadQueue* Frontend::LockQueue()
{
return DownloadQueue::Lock();
}
void Frontend::UnlockQueue()
{
DownloadQueue::Unlock();
}
bool Frontend::IsRemoteMode()
{
return g_Options->GetRemoteClientMode();
}
void Frontend::ServerPauseUnpause(bool pause)
{
if (IsRemoteMode())
{
RequestPauseUnpause(pause);
}
else
{
g_Options->SetResumeTime(0);
g_Options->SetPauseDownload(pause);
}
}
void Frontend::ServerSetDownloadRate(int rate)
{
if (IsRemoteMode())
{
RequestSetDownloadRate(rate);
}
else
{
g_Options->SetDownloadRate(rate);
}
}
bool Frontend::ServerEditQueue(DownloadQueue::EEditAction action, int offset, int id)
{
if (IsRemoteMode())
{
return RequestEditQueue(action, offset, id);
}
else
{
DownloadQueue* downloadQueue = LockQueue();
bool ok = downloadQueue->EditEntry(id, action, offset, nullptr);
UnlockQueue();
return ok;
}
return false;
}
void Frontend::InitMessageBase(SNzbRequestBase* messageBase, int request, int size)
{
messageBase->m_signature = htonl(NZBMESSAGE_SIGNATURE);
messageBase->m_type = htonl(request);
messageBase->m_structSize = htonl(size);
strncpy(messageBase->m_username, g_Options->GetControlUsername(), NZBREQUESTPASSWORDSIZE - 1);
messageBase->m_username[NZBREQUESTPASSWORDSIZE - 1] = '\0';
strncpy(messageBase->m_password, g_Options->GetControlPassword(), NZBREQUESTPASSWORDSIZE);
messageBase->m_password[NZBREQUESTPASSWORDSIZE - 1] = '\0';
}
bool Frontend::RequestMessages()
{
const char* controlIp = !strcmp(g_Options->GetControlIp(), "0.0.0.0") ? "127.0.0.1" : g_Options->GetControlIp();
Connection connection(controlIp, g_Options->GetControlPort(), false);
bool OK = connection.Connect();
if (!OK)
{
return false;
}
SNzbLogRequest LogRequest;
InitMessageBase(&LogRequest.m_messageBase, rrLog, sizeof(LogRequest));
LogRequest.m_lines = htonl(m_neededLogEntries);
if (m_neededLogEntries == 0)
{
LogRequest.m_idFrom = htonl(m_neededLogFirstId > 0 ? m_neededLogFirstId : 1);
}
else
{
LogRequest.m_idFrom = 0;
}
if (!connection.Send((char*)(&LogRequest), sizeof(LogRequest)))
{
return false;
}
// Now listen for the returned log
SNzbLogResponse LogResponse;
bool read = connection.Recv((char*) &LogResponse, sizeof(LogResponse));
if (!read ||
(int)ntohl(LogResponse.m_messageBase.m_signature) != (int)NZBMESSAGE_SIGNATURE ||
ntohl(LogResponse.m_messageBase.m_structSize) != sizeof(LogResponse))
{
return false;
}
CharBuffer buf;
if (ntohl(LogResponse.m_trailingDataLength) > 0)
{
buf.Reserve(ntohl(LogResponse.m_trailingDataLength));
if (!connection.Recv(buf, buf.Size()))
{
return false;
}
}
connection.Disconnect();
if (ntohl(LogResponse.m_trailingDataLength) > 0)
{
char* bufPtr = (char*)buf;
for (uint32 i = 0; i < ntohl(LogResponse.m_nrTrailingEntries); i++)
{
SNzbLogResponseEntry* logAnswer = (SNzbLogResponseEntry*) bufPtr;
char* text = bufPtr + sizeof(SNzbLogResponseEntry);
m_remoteMessages.emplace_back(ntohl(logAnswer->m_id), (Message::EKind)ntohl(logAnswer->m_kind), ntohl(logAnswer->m_time), text);
bufPtr += sizeof(SNzbLogResponseEntry) + ntohl(logAnswer->m_textLen);
}
}
return true;
}
bool Frontend::RequestFileList()
{
const char* controlIp = !strcmp(g_Options->GetControlIp(), "0.0.0.0") ? "127.0.0.1" : g_Options->GetControlIp();
Connection connection(controlIp, g_Options->GetControlPort(), false);
bool OK = connection.Connect();
if (!OK)
{
return false;
}
SNzbListRequest ListRequest;
InitMessageBase(&ListRequest.m_messageBase, rrList, sizeof(ListRequest));
ListRequest.m_fileList = htonl(m_fileList);
ListRequest.m_serverState = htonl(m_summary);
if (!connection.Send((char*)(&ListRequest), sizeof(ListRequest)))
{
return false;
}
// Now listen for the returned list
SNzbListResponse ListResponse;
bool read = connection.Recv((char*) &ListResponse, sizeof(ListResponse));
if (!read ||
(int)ntohl(ListResponse.m_messageBase.m_signature) != (int)NZBMESSAGE_SIGNATURE ||
ntohl(ListResponse.m_messageBase.m_structSize) != sizeof(ListResponse))
{
return false;
}
CharBuffer buf;
if (ntohl(ListResponse.m_trailingDataLength) > 0)
{
buf.Reserve(ntohl(ListResponse.m_trailingDataLength));
if (!connection.Recv(buf, buf.Size()))
{
return false;
}
}
connection.Disconnect();
if (m_summary)
{
m_pauseDownload = ntohl(ListResponse.m_downloadPaused);
m_remainingSize = Util::JoinInt64(ntohl(ListResponse.m_remainingSizeHi), ntohl(ListResponse.m_remainingSizeLo));
m_currentDownloadSpeed = ntohl(ListResponse.m_downloadRate);
m_downloadLimit = ntohl(ListResponse.m_downloadLimit);
m_threadCount = ntohl(ListResponse.m_threadCount);
m_postJobCount = ntohl(ListResponse.m_postJobCount);
m_upTimeSec = ntohl(ListResponse.m_upTimeSec);
m_dnTimeSec = ntohl(ListResponse.m_downloadTimeSec);
m_standBy = ntohl(ListResponse.m_downloadStandBy);
m_allBytes = Util::JoinInt64(ntohl(ListResponse.m_downloadedBytesHi), ntohl(ListResponse.m_downloadedBytesLo));
}
if (m_fileList && ntohl(ListResponse.m_trailingDataLength) > 0)
{
RemoteClient client;
client.SetVerbose(false);
DownloadQueue* downloadQueue = LockQueue();
client.BuildFileList(&ListResponse, buf, downloadQueue);
UnlockQueue();
}
return true;
}
bool Frontend::RequestPauseUnpause(bool pause)
{
RemoteClient client;
client.SetVerbose(false);
return client.RequestServerPauseUnpause(pause, rpDownload);
}
bool Frontend::RequestSetDownloadRate(int rate)
{
RemoteClient client;
client.SetVerbose(false);
return client.RequestServerSetDownloadRate(rate);
}
bool Frontend::RequestEditQueue(DownloadQueue::EEditAction action, int offset, int id)
{
RemoteClient client;
client.SetVerbose(false);
IdList ids = { id };
return client.RequestServerEditQueue(action, offset, nullptr, &ids, nullptr, rmId);
}